]> git.sur5r.net Git - bacula/bacula/commitdiff
Implement Device Spool directory and sizes
authorKern Sibbald <kern@sibbald.com>
Wed, 10 Mar 2004 20:12:32 +0000 (20:12 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 10 Mar 2004 20:12:32 +0000 (20:12 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1121 91ce42f0-d328-0410-95d8-f526ca767f89

17 files changed:
bacula/src/dird/dird_conf.h
bacula/src/lib/bsock.h
bacula/src/lib/message.c
bacula/src/lib/protos.h
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/bcopy.c
bacula/src/stored/block.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/dircmd.c
bacula/src/stored/protos.h
bacula/src/stored/spool.c
bacula/src/stored/stored_conf.c
bacula/src/stored/stored_conf.h
bacula/src/version.h

index 56bddbdc8d87dd7a8b0ca21cf44f19b5d14fc069..ee63b8a6beb22efc50de544dcd2ebb166aa2d300 100644 (file)
@@ -42,33 +42,35 @@ enum {
    R_MSGS,
    R_COUNTER,
    R_CONSOLE,
-   R_JOBDEFS
+   R_JOBDEFS,
+   R_FIRST = R_DIRECTOR,
+   R_LAST  = R_JOBDEFS                /* keep this updated */
 };
 
-#define R_FIRST  R_DIRECTOR
-#define R_LAST  R_JOBDEFS    
 
 /*
  * Some resource attributes
  */
-#define R_NAME               1020
-#define R_ADDRESS            1021
-#define R_PASSWORD           1022
-#define R_TYPE               1023
-#define R_BACKUP             1024
+enum {
+   R_NAME = 1020,
+   R_ADDRESS,
+   R_PASSWORD,
+   R_TYPE,
+   R_BACKUP
+};
 
 
 /* Used for certain KeyWord tables */
-struct s_kw {      
+struct s_kw {       
    char *name;
-   int token;  
+   int token;   
 };
 
 /* Job Level keyword structure */
 struct s_jl {
-   char *level_name;                 /* level keyword */
-   int level;                        /* level */
-   int job_type;                     /* JobType permitting this level */
+   char *level_name;                  /* level keyword */
+   int  level;                        /* level */
+   int  job_type;                     /* JobType permitting this level */
 };
 
 /* Job Type keyword structure */
@@ -86,24 +88,24 @@ struct POOL;
 struct RUN;
 
 /* 
- *   Director Resource 
+ *   Director Resource  
  *
  */
 struct DIRRES {
-   RES  hdr;
-   int  DIRport;                     /* where we listen -- UA port server port */
-   char *DIRaddr;                    /* bind address */
-   char *password;                   /* Password for UA access */
-   int enable_ssl;                   /* Use SSL for UA */
-   char *query_file;                 /* SQL query file */
-   char *working_directory;          /* WorkingDirectory */
-   char *pid_directory;              /* PidDirectory */
-   char *subsys_directory;           /* SubsysDirectory */
-   int require_ssl;                  /* Require SSL for all connections */
-   MSGS *messages;                   /* Daemon message handler */
-   uint32_t MaxConcurrentJobs;       /* Max concurrent jobs for whole director */
-   utime_t FDConnectTimeout;         /* timeout for connect in seconds */
-   utime_t SDConnectTimeout;         /* timeout in seconds */
+   RES   hdr;
+   int   DIRport;                     /* where we listen -- UA port server port */
+   char *DIRaddr;                     /* bind address */
+   char *password;                    /* Password for UA access */
+   int enable_ssl;                    /* Use SSL for UA */
+   char *query_file;                  /* SQL query file */
+   char *working_directory;           /* WorkingDirectory */
+   char *pid_directory;               /* PidDirectory */
+   char *subsys_directory;            /* SubsysDirectory */
+   int require_ssl;                   /* Require SSL for all connections */
+   MSGS *messages;                    /* Daemon message handler */
+   uint32_t MaxConcurrentJobs;        /* Max concurrent jobs for whole director */
+   utime_t FDConnectTimeout;          /* timeout for connect in seconds */
+   utime_t SDConnectTimeout;          /* timeout in seconds */
 };
 
 
@@ -120,17 +122,17 @@ enum {
    Command_ACL,
    FileSet_ACL,
    Catalog_ACL,
-   Num_ACL                           /* keep last */
+   Num_ACL                            /* keep last */
 };
 
 /* 
  *    Console Resource
  */
 struct CONRES {
-   RES  hdr;
-   char *password;                   /* UA server password */
-   int enable_ssl;                   /* Use SSL */
-   alist *ACL_lists[Num_ACL];        /* pointers to ACLs */
+   RES   hdr;
+   char *password;                    /* UA server password */
+   int enable_ssl;                    /* Use SSL */
+   alist *ACL_lists[Num_ACL];         /* pointers to ACLs */
 };
 
 
@@ -139,11 +141,11 @@ struct CONRES {
  *
  */
 struct CAT {
-   RES  hdr;
+   RES   hdr;
 
-   int  db_port;                     /* Port -- not yet implemented */
-   char *db_address;                 /* host name for remote access */
-   char *db_socket;                  /* Socket for local access */
+   int   db_port;                     /* Port -- not yet implemented */
+   char *db_address;                  /* host name for remote access */
+   char *db_socket;                   /* Socket for local access */
    char *db_password;
    char *db_user;
    char *db_name;
@@ -155,18 +157,18 @@ struct CAT {
  *
  */
 struct CLIENT {
-   RES  hdr;
+   RES   hdr;
 
-   int  FDport;                      /* Where File daemon listens */
-   int  AutoPrune;                   /* Do automatic pruning? */
-   utime_t FileRetention;            /* file retention period in seconds */
-   utime_t JobRetention;             /* job retention period in seconds */
+   int   FDport;                      /* Where File daemon listens */
+   int   AutoPrune;                   /* Do automatic pruning? */
+   utime_t FileRetention;             /* file retention period in seconds */
+   utime_t JobRetention;              /* job retention period in seconds */
    char *address;
    char *password;
-   CAT *catalog;                     /* Catalog resource */
-   uint32_t MaxConcurrentJobs;       /* Maximume concurrent jobs */
-   uint32_t NumConcurrentJobs;       /* number of concurrent jobs running */
-   int enable_ssl;                   /* Use SSL */
+   CAT *catalog;                      /* Catalog resource */
+   uint32_t MaxConcurrentJobs;        /* Maximume concurrent jobs */
+   uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
+   int enable_ssl;                    /* Use SSL */
 };
 
 /*
@@ -174,18 +176,18 @@ struct CLIENT {
  * 
  */
 struct STORE {
-   RES  hdr;
+   RES   hdr;
 
-   int  SDport;                      /* port where Directors connect */
-   int  SDDport;                     /* data port for File daemon */
+   int   SDport;                      /* port where Directors connect */
+   int   SDDport;                     /* data port for File daemon */
    char *address;
    char *password;
    char *media_type;
    char *dev_name;   
-   int autochanger;                  /* set if autochanger */
-   uint32_t MaxConcurrentJobs;       /* Maximume concurrent jobs */
-   uint32_t NumConcurrentJobs;       /* number of concurrent jobs running */
-   int enable_ssl;                   /* Use SSL */
+   int  autochanger;                  /* set if autochanger */
+   uint32_t MaxConcurrentJobs;        /* Maximume concurrent jobs */
+   uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
+   int enable_ssl;                    /* Use SSL */
 };
 
 
@@ -193,66 +195,66 @@ struct STORE {
  *   Job Resource
  */
 struct JOB {
-   RES  hdr;
-
-   int  JobType;                     /* job type (backup, verify, restore */
-   int  level;                       /* default backup/verify level */
-   int  Priority;                    /* Job priority */
-   int  RestoreJobId;                /* What -- JobId to restore */
-   char *RestoreWhere;               /* Where on disk to restore -- directory */
-   char *RestoreBootstrap;           /* Bootstrap file */
-   char *RunBeforeJob;               /* Run program before Job */
-   char *RunAfterJob;                /* Run program after Job */
-   char *RunAfterFailedJob;          /* Run program after Job that errs */
-   char *ClientRunBeforeJob;         /* Run client program before Job */
-   char *ClientRunAfterJob;          /* Run client program after Job */
-   char *WriteBootstrap;             /* Where to write bootstrap Job updates */
-   int  replace;                     /* How (overwrite, ..) */
-   utime_t MaxRunTime;               /* max run time in seconds */
-   utime_t MaxWaitTime;              /* max blocking time in seconds */
-   utime_t MaxStartDelay;            /* max start delay in seconds */
-   int PrefixLinks;                  /* prefix soft links with Where path */
-   int PruneJobs;                    /* Force pruning of Jobs */
-   int PruneFiles;                   /* Force pruning of Files */
-   int PruneVolumes;                 /* Force pruning of Volumes */
-   int SpoolAttributes;              /* Set to spool attributes in SD */
-   int spool_data;                   /* Set to spool data in SD */
-   uint32_t MaxConcurrentJobs;       /* Maximume concurrent jobs */
-   int RescheduleOnError;            /* Set to reschedule on error */
-   int RescheduleTimes;              /* Number of times to reschedule job */
-   utime_t RescheduleInterval;       /* Reschedule interval */
-   utime_t JobRetention;             /* job retention period in seconds */
+   RES   hdr;
+
+   int   JobType;                     /* job type (backup, verify, restore */
+   int   level;                       /* default backup/verify level */
+   int   Priority;                    /* Job priority */
+   int   RestoreJobId;                /* What -- JobId to restore */
+   char *RestoreWhere;                /* Where on disk to restore -- directory */
+   char *RestoreBootstrap;            /* Bootstrap file */
+   char *RunBeforeJob;                /* Run program before Job */
+   char *RunAfterJob;                 /* Run program after Job */
+   char *RunAfterFailedJob;           /* Run program after Job that errs */
+   char *ClientRunBeforeJob;          /* Run client program before Job */
+   char *ClientRunAfterJob;           /* Run client program after Job */
+   char *WriteBootstrap;              /* Where to write bootstrap Job updates */
+   int   replace;                     /* How (overwrite, ..) */
+   utime_t MaxRunTime;                /* max run time in seconds */
+   utime_t MaxWaitTime;               /* max blocking time in seconds */
+   utime_t MaxStartDelay;             /* max start delay in seconds */
+   int PrefixLinks;                   /* prefix soft links with Where path */
+   int PruneJobs;                     /* Force pruning of Jobs */
+   int PruneFiles;                    /* Force pruning of Files */
+   int PruneVolumes;                  /* Force pruning of Volumes */
+   int SpoolAttributes;               /* Set to spool attributes in SD */
+   int spool_data;                    /* Set to spool data in SD */
+   uint32_t MaxConcurrentJobs;        /* Maximume concurrent jobs */
+   int RescheduleOnError;             /* Set to reschedule on error */
+   int RescheduleTimes;               /* Number of times to reschedule job */
+   utime_t RescheduleInterval;        /* Reschedule interval */
+   utime_t JobRetention;              /* job retention period in seconds */
   
-   MSGS      *messages;              /* How and where to send messages */
-   SCHED     *schedule;              /* When -- Automatic schedule */
-   CLIENT    *client;                /* Who to backup */
-   FILESET   *fileset;               /* What to backup -- Fileset */
-   STORE     *storage;               /* Where is device -- Storage daemon */
-   POOL      *pool;                  /* Where is media -- Media Pool */
-   POOL      *full_pool;             /* Pool for Full backups */
-   POOL      *inc_pool;              /* Pool for Incremental backups */
-   POOL      *dif_pool;              /* Pool for Differental backups */
-   JOB      *verify_job;             /* Job name to verify */
-   JOB      *jobdefs;                /* Job defaults */
-   uint32_t NumConcurrentJobs;       /* number of concurrent jobs running */
+   MSGS      *messages;               /* How and where to send messages */
+   SCHED     *schedule;               /* When -- Automatic schedule */
+   CLIENT    *client;                 /* Who to backup */
+   FILESET   *fileset;                /* What to backup -- Fileset */
+   STORE     *storage;                /* Where is device -- Storage daemon */
+   POOL      *pool;                   /* Where is media -- Media Pool */
+   POOL      *full_pool;              /* Pool for Full backups */
+   POOL      *inc_pool;               /* Pool for Incremental backups */
+   POOL      *dif_pool;               /* Pool for Differental backups */
+   JOB       *verify_job;             /* Job name to verify */
+   JOB       *jobdefs;                /* Job defaults */
+   uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
 };
 
 #define MAX_FOPTS 30
 
 /* File options structure */
 struct FOPTS {
-   char opts[MAX_FOPTS];             /* options string */
-   alist match;                      /* match string(s) */
-   alist base_list;                  /* list of base names */
+   char opts[MAX_FOPTS];              /* options string */
+   alist match;                       /* match string(s) */
+   alist base_list;                   /* list of base names */
 };
 
 
 /* This is either an include item or an exclude item */
 struct INCEXE {
-   FOPTS *current_opts;              /* points to current options structure */
-   FOPTS **opts_list;                /* options list */
-   int num_opts;                     /* number of options items */
-   alist name_list;                  /* filename list -- holds char * */
+   FOPTS *current_opts;               /* points to current options structure */
+   FOPTS **opts_list;                 /* options list */
+   int num_opts;                      /* number of options items */
+   alist name_list;                   /* filename list -- holds char * */
 };
 
 /* 
@@ -260,16 +262,16 @@ struct INCEXE {
  *
  */
 struct FILESET {
-   RES  hdr;
+   RES   hdr;
 
-   int new_include;                  /* Set if new include used */
-   INCEXE **include_items;           /* array of incexe structures */
-   int num_includes;                 /* number in array */
+   int new_include;                   /* Set if new include used */
+   INCEXE **include_items;            /* array of incexe structures */
+   int num_includes;                  /* number in array */
    INCEXE **exclude_items;
    int num_excludes;
-   int have_MD5;                     /* set if MD5 initialized */
-   struct MD5Context md5c;           /* MD5 of include/exclude */
-   char MD5[30];                     /* base 64 representation of MD5 */
+   int have_MD5;                      /* set if MD5 initialized */
+   struct MD5Context md5c;            /* MD5 of include/exclude */
+   char MD5[30];                      /* base 64 representation of MD5 */
 };
 
  
@@ -278,7 +280,7 @@ struct FILESET {
  *
  */
 struct SCHED {
-   RES  hdr;
+   RES   hdr;
 
    RUN *run;
 };
@@ -287,14 +289,14 @@ struct SCHED {
  *   Counter Resource
  */
 struct COUNTER {
-   RES  hdr;
-
-   int32_t  MinValue;                /* Minimum value */
-   int32_t  MaxValue;                /* Maximum value */
-   int32_t  CurrentValue;            /* Current value */
-   COUNTER *WrapCounter;             /* Wrap counter name */
-   CAT    *Catalog;                  /* Where to store */
-   bool     created;                 /* Created in DB */
+   RES   hdr;
+
+   int32_t  MinValue;                 /* Minimum value */
+   int32_t  MaxValue;                 /* Maximum value */
+   int32_t  CurrentValue;             /* Current value */
+   COUNTER *WrapCounter;              /* Wrap counter name */
+   CAT     *Catalog;                  /* Where to store */
+   bool     created;                  /* Created in DB */
 };
 
 /*
@@ -302,26 +304,26 @@ struct COUNTER {
  *
  */
 struct POOL {
-   RES  hdr;
-
-   char *pool_type;                  /* Pool type */
-   char *label_format;               /* Label format string */
-   char *cleaning_prefix;            /* Cleaning label prefix */
-   int  use_catalog;                 /* maintain catalog for media */
-   int  catalog_files;               /* maintain file entries in catalog */
-   int  use_volume_once;             /* write on volume only once */
-   int  accept_any_volume;           /* accept any volume */
-   int  purge_oldest_volume;         /* purge oldest volume */
-   int  recycle_oldest_volume;       /* attempt to recycle oldest volume */
-   int  recycle_current_volume;      /* attempt recycle of current volume */
-   uint32_t max_volumes;             /* max number of volumes */
-   utime_t VolRetention;             /* volume retention period in seconds */
-   utime_t VolUseDuration;           /* duration volume can be used */
-   uint32_t MaxVolJobs;              /* Maximum jobs on the Volume */
-   uint32_t MaxVolFiles;             /* Maximum files on the Volume */
-   uint64_t MaxVolBytes;             /* Maximum bytes on the Volume */
-   int  AutoPrune;                   /* default for pool auto prune */
-   int  Recycle;                     /* default for media recycle yes/no */
+   RES   hdr;
+
+   char *pool_type;                   /* Pool type */
+   char *label_format;                /* Label format string */
+   char *cleaning_prefix;             /* Cleaning label prefix */
+   int   use_catalog;                 /* maintain catalog for media */
+   int   catalog_files;               /* maintain file entries in catalog */
+   int   use_volume_once;             /* write on volume only once */
+   int   accept_any_volume;           /* accept any volume */
+   int   purge_oldest_volume;         /* purge oldest volume */
+   int   recycle_oldest_volume;       /* attempt to recycle oldest volume */
+   int   recycle_current_volume;      /* attempt recycle of current volume */
+   uint32_t max_volumes;              /* max number of volumes */
+   utime_t VolRetention;              /* volume retention period in seconds */
+   utime_t VolUseDuration;            /* duration volume can be used */
+   uint32_t MaxVolJobs;               /* Maximum jobs on the Volume */
+   uint32_t MaxVolFiles;              /* Maximum files on the Volume */
+   uint64_t MaxVolBytes;              /* Maximum bytes on the Volume */
+   int   AutoPrune;                   /* default for pool auto prune */
+   int   Recycle;                     /* default for media recycle yes/no */
 };
 
 
@@ -333,37 +335,37 @@ union URES {
    CONRES     res_con;
    CLIENT     res_client;
    STORE      res_store;
-   CAT       res_cat;
-   JOB       res_job;
+   CAT        res_cat;
+   JOB        res_job;
    FILESET    res_fs;
    SCHED      res_sch;
    POOL       res_pool;
    MSGS       res_msgs;
    COUNTER    res_counter;
-   RES       hdr;
+   RES        hdr;
 };
 
 
 
 /* Run structure contained in Schedule Resource */
 struct RUN {
-   RUN *next;                        /* points to next run record */
-   int level;                        /* level override */
-   int Priority;                     /* priority override */
+   RUN *next;                         /* points to next run record */
+   int level;                         /* level override */
+   int Priority;                      /* priority override */
    int job_type;  
-   bool spool_data;                  /* Data spooling override */
-   bool spool_data_set;              /* Data spooling override given */
-   POOL *pool;                       /* Pool override */
-   POOL *full_pool;                  /* Pool override */
-   POOL *inc_pool;                   /* Pool override */
-   POOL *dif_pool;                   /* Pool override */
-   STORE *storage;                   /* Storage override */
-   MSGS *msgs;                       /* Messages override */
+   bool spool_data;                   /* Data spooling override */
+   bool spool_data_set;               /* Data spooling override given */
+   POOL *pool;                        /* Pool override */
+   POOL *full_pool;                   /* Pool override */
+   POOL *inc_pool;                    /* Pool override */
+   POOL *dif_pool;                    /* Pool override */
+   STORE *storage;                    /* Storage override */
+   MSGS *msgs;                        /* Messages override */
    char *since;
    int level_no;
-   int minute;                       /* minute to run job */
-   time_t last_run;                  /* last time run */
-   time_t next_run;                  /* next time to run */
+   int minute;                        /* minute to run job */
+   time_t last_run;                   /* last time run */
+   time_t next_run;                   /* next time to run */
    char hour[nbytes_for_bits(24)];    /* bit set for each hour */
    char mday[nbytes_for_bits(31)];    /* bit set for each day of month */
    char month[nbytes_for_bits(12)];   /* bit set for each month */
index 49af7fbc5337ffa7817e2643bcafdf50eee948a6..39fc21af994192afe514ab87e91d5a562d672d5b 100644 (file)
  */
 
 struct BSOCK {
-   uint64_t read_seqno;              /* read sequence number */
-   uint32_t in_msg_no;               /* input message number */
-   uint32_t out_msg_no;              /* output message number */
-   int fd;                           /* socket file descriptor */
-   int32_t msglen;                   /* message length */
-   int b_errno;                      /* bsock errno */
-   int port;                         /* desired port */
-   volatile bool errors: 1;          /* set if errors on socket */
+   uint64_t read_seqno;               /* read sequence number */
+   uint32_t in_msg_no;                /* input message number */
+   uint32_t out_msg_no;               /* output message number */
+   int fd;                            /* socket file descriptor */
+   int32_t msglen;                    /* message length */
+   int b_errno;                       /* bsock errno */
+   int port;                          /* desired port */
+   volatile bool errors: 1;           /* set if errors on socket */
    volatile bool suppress_error_msgs: 1; /* set to suppress error messages */
-   volatile bool timed_out: 1;       /* timed out in read/write */
+   volatile bool timed_out: 1;        /* timed out in read/write */
    volatile bool terminated: 1;       /* set when BNET_TERMINATE arrives */
-   bool duped: 1;                    /* set if duped BSOCK */
-   bool spool: 1;                     /* set for spooling */
+   bool duped: 1;                     /* set if duped BSOCK */
+   bool spool: 1;                     /* set for spooling */
    volatile time_t timer_start;       /* time started read/write */
-   volatile time_t timeout;          /* timeout BSOCK after this interval */
-   POOLMEM *msg;                     /* message pool buffer */
-   char *who;                        /* Name of daemon to which we are talking */
-   char *host;                       /* Host name/IP */
-   POOLMEM *errmsg;                  /* edited error message (to be implemented) */
-   RES *res;                         /* Resource to which we are connected */
-   BSOCK *next;                      /* next BSOCK if duped */
-   FILE *spool_fd;                   /* spooling file */
-   JCR *jcr;                         /* jcr or NULL for error msgs */
+   volatile time_t timeout;           /* timeout BSOCK after this interval */
+   POOLMEM *msg;                      /* message pool buffer */
+   char *who;                         /* Name of daemon to which we are talking */
+   char *host;                        /* Host name/IP */
+   POOLMEM *errmsg;                   /* edited error message (to be implemented) */
+   RES *res;                          /* Resource to which we are connected */
+   BSOCK *next;                       /* next BSOCK if duped */
+   FILE *spool_fd;                    /* spooling file */
+   JCR *jcr;                          /* jcr or NULL for error msgs */
    struct sockaddr_in client_addr;    /* client's IP address */
-};     
+};      
 
 /* Signal definitions for use in bnet_sig() */
 enum {
-   BNET_EOD           = -1,          /* End of data stream, new data may follow */
-   BNET_EOD_POLL       = -2,         /* End of data and poll all in one */
-   BNET_STATUS        = -3,          /* Send full status */
-   BNET_TERMINATE      = -4,         /* Conversation terminated, doing close() */
+   BNET_EOD            = -1,          /* End of data stream, new data may follow */
+   BNET_EOD_POLL       = -2,          /* End of data and poll all in one */
+   BNET_STATUS         = -3,          /* Send full status */
+   BNET_TERMINATE      = -4,          /* Conversation terminated, doing close() */
    BNET_POLL           = -5,          /* Poll request, I'm hanging on a read */
-   BNET_HEARTBEAT      = -6,         /* Heartbeat Response requested */
-   BNET_HB_RESPONSE    = -7,         /* Only response permited to HB */
-   BNET_PROMPT        = -8,          /* Prompt for UA */
-   BNET_BTIME         = -9,          /* Send UTC btime */
-   BNET_BREAK         = -10          /* Stop current command -- ctl-c */
+   BNET_HEARTBEAT      = -6,          /* Heartbeat Response requested */
+   BNET_HB_RESPONSE    = -7,          /* Only response permited to HB */
+   BNET_PROMPT         = -8,          /* Prompt for UA */
+   BNET_BTIME          = -9,          /* Send UTC btime */
+   BNET_BREAK          = -10          /* Stop current command -- ctl-c */
 };
 
-#define BNET_SETBUF_READ  1          /* Arg for bnet_set_buffer_size */
-#define BNET_SETBUF_WRITE 2          /* Arg for bnet_set_buffer_size */
+#define BNET_SETBUF_READ  1           /* Arg for bnet_set_buffer_size */
+#define BNET_SETBUF_WRITE 2           /* Arg for bnet_set_buffer_size */
 
 /* Return status from bnet_recv() */
 #define BNET_SIGNAL  -1
@@ -81,25 +81,25 @@ enum {
 #define BNET_ERROR   -3
 
 /* SSL enabling values */
-#define BNET_SSL_NONE    0           /* cannot do SSL */
-#define BNET_SSL_OK      1           /* can do, but not required on my end */
-#define BNET_SSL_REQUIRED 2          /* SSL is required */
+#define BNET_SSL_NONE     0           /* cannot do SSL */
+#define BNET_SSL_OK       1           /* can do, but not required on my end */
+#define BNET_SSL_REQUIRED 2           /* SSL is required */
 
 /*
  * This is the structure of the in memory BPKT
  */
 typedef struct s_bpkt {
-   char *id;                         /* String identifier or name of field */
-   uint8_t type;                     /* field type */
-   uint32_t len;                     /* field length for string, name, bytes */
-   void *value;                      /* pointer to value */
+   char *id;                          /* String identifier or name of field */
+   uint8_t type;                      /* field type */
+   uint32_t len;                      /* field length for string, name, bytes */
+   void *value;                       /* pointer to value */
 } BPKT;
 
 /*  
  * These are the data types that can be sent.
  * For all values other than string, the storage space
  *  is assumed to be allocated in the receiving packet.
- *  For BP_STRING if the *value is non-zero, it is a       
+ *  For BP_STRING if the *value is non-zero, it is a        
  *  pointer to a POOLMEM buffer, and the Memory Pool
  *  routines will be used to assure that the length is
  *  adequate. NOTE!!! This pointer will be changed
@@ -107,13 +107,13 @@ typedef struct s_bpkt {
  *  does). If the pointer is NULL, a POOLMEM
  *  buffer will be allocated.
  */
-#define BP_EOF      0                /* end of file */
-#define BP_CHAR      1               /* Character */
-#define BP_INT32     1               /* 32 bit integer */
-#define BP_UINT32    3               /* Unsigned 32 bit integer */
-#define BP_INT64     4               /* 64 bit integer */
-#define BP_STRING    5               /* string */
-#define BP_NAME      6               /* Name string -- limited length */
-#define BP_BYTES     7               /* Binary bytes */
-#define BP_FLOAT32   8               /* 32 bit floating point */
-#define BP_FLOAT64   9               /* 64 bit floating point */
+#define BP_EOF       0                /* end of file */
+#define BP_CHAR      1                /* Character */
+#define BP_INT32     1                /* 32 bit integer */
+#define BP_UINT32    3                /* Unsigned 32 bit integer */
+#define BP_INT64     4                /* 64 bit integer */
+#define BP_STRING    5                /* string */
+#define BP_NAME      6                /* Name string -- limited length */
+#define BP_BYTES     7                /* Binary bytes */
+#define BP_FLOAT32   8                /* 32 bit floating point */
+#define BP_FLOAT64   9                /* 64 bit floating point */
index 77de72c4e9c85f35861cc24fc1992675dfede68d..c8f9aac557ea908212749300e6ef6657baf1fd08 100755 (executable)
@@ -339,39 +339,6 @@ void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where)
    }
 }
 
-static void make_unique_spool_filename(JCR *jcr, POOLMEM **name, int fd)
-{
-   Mmsg(name, "%s/%s.spool.%s.%d", working_directory, my_name,
-      jcr->Job, fd);
-}
-
-int open_spool_file(JCR *jcr, BSOCK *bs)
-{
-    POOLMEM *name  = get_pool_memory(PM_MESSAGE);
-
-    make_unique_spool_filename(jcr, &name, bs->fd);
-    bs->spool_fd = fopen(mp_chr(name), "w+");
-    if (!bs->spool_fd) {
-       Jmsg(jcr, M_ERROR, 0, "fopen spool file %s failed: ERR=%s\n", name, strerror(errno));
-       free_pool_memory(name);
-       return 0;
-    }
-    free_pool_memory(name);
-    return 1;
-}
-
-int close_spool_file(JCR *jcr, BSOCK *bs)
-{
-    POOLMEM *name  = get_pool_memory(PM_MESSAGE);
-
-    make_unique_spool_filename(jcr, &name, bs->fd);
-    fclose(bs->spool_fd);
-    unlink(mp_chr(name));
-    free_pool_memory(name);
-    bs->spool_fd = NULL;
-    bs->spool = 0;
-    return 1;
-}
 
 /*
  * Create a unique filename for the mail command
index 6269700a6fb9c1f1ddac5bbfa2489f87c8681346..fa2d82b6a4aafbeb6e8363e9ccef07116f7023fa 100644 (file)
 struct JCR;
 
 /* attr.c */
-ATTR    *new_attr();
-void     free_attr(ATTR *attr);
-int      unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr);
-void     build_attr_output_fnames(JCR *jcr, ATTR *attr);
-void     print_ls_output(JCR *jcr, ATTR *attr);
+ATTR     *new_attr();
+void      free_attr(ATTR *attr);
+int       unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr);
+void      build_attr_output_fnames(JCR *jcr, ATTR *attr);
+void      print_ls_output(JCR *jcr, ATTR *attr);
 
 /* base64.c */
-void     base64_init            (void);
-int      to_base64              (intmax_t value, char *where);
-int      from_base64            (intmax_t *value, char *where);
-int      bin_to_base64          (char *buf, char *bin, int len);
+void      base64_init            (void);
+int       to_base64              (intmax_t value, char *where);
+int       from_base64            (intmax_t *value, char *where);
+int       bin_to_base64          (char *buf, char *bin, int len);
 
 /* bsys.c */
-char    *bstrncpy               (char *dest, const char *src, int maxlen);
-char    *bstrncat               (char *dest, const char *src, int maxlen);
-void    *b_malloc               (const char *file, int line, size_t size);
+char     *bstrncpy               (char *dest, const char *src, int maxlen);
+char     *bstrncat               (char *dest, const char *src, int maxlen);
+void     *b_malloc               (const char *file, int line, size_t size);
 #ifndef DEBUG
-void    *bmalloc                (size_t size);
+void     *bmalloc                (size_t size);
 #endif
-void    *brealloc               (void *buf, size_t size);
-void    *bcalloc                (size_t size1, size_t size2);
-int      bsnprintf              (char *str, int32_t size, const char *format, ...);
-int      bvsnprintf             (char *str, int32_t size, const char *format, va_list ap);
-int      pool_sprintf           (char *pool_buf, const char *fmt, ...);
-void     create_pid_file        (char *dir, const char *progname, int port);
-int      delete_pid_file        (char *dir, const char *progname, int port);
-void     drop                   (char *uid, char *gid);
-int      bmicrosleep            (time_t sec, long usec);
-char    *bfgets                 (char *s, int size, FILE *fd);
-void     make_unique_filename   (POOLMEM **name, int Id, char *what);
+void     *brealloc               (void *buf, size_t size);
+void     *bcalloc                (size_t size1, size_t size2);
+int       bsnprintf              (char *str, int32_t size, const char *format, ...);
+int       bvsnprintf             (char *str, int32_t size, const char *format, va_list ap);
+int       pool_sprintf           (char *pool_buf, const char *fmt, ...);
+void      create_pid_file        (char *dir, const char *progname, int port);
+int       delete_pid_file        (char *dir, const char *progname, int port);
+void      drop                   (char *uid, char *gid);
+int       bmicrosleep            (time_t sec, long usec);
+char     *bfgets                 (char *s, int size, FILE *fd);
+void      make_unique_filename   (POOLMEM **name, int Id, char *what);
 #ifndef HAVE_STRTOLL
-long long int strtoll           (const char *ptr, char **endptr, int base);
+long long int strtoll            (const char *ptr, char **endptr, int base);
 #endif
 void read_state_file(char *dir, const char *progname, int port);
 
 /* bnet.c */
-int32_t    bnet_recv            (BSOCK *bsock);
-int       bnet_send             (BSOCK *bsock);
-int       bnet_fsend            (BSOCK *bs, const char *fmt, ...);
-int       bnet_set_buffer_size  (BSOCK *bs, uint32_t size, int rw);
-int       bnet_sig              (BSOCK *bs, int sig);
-int       bnet_ssl_server       (BSOCK *bsock, char *password, int ssl_need, int ssl_has);
-int       bnet_ssl_client       (BSOCK *bsock, char *password, int ssl_need);
-BSOCK *    bnet_connect           (JCR *jcr, int retry_interval,
-              int max_retry_time, const char *name, char *host, char *service, 
-              int port, int verbose);
-void      bnet_close            (BSOCK *bsock);
-BSOCK *    init_bsock           (JCR *jcr, int sockfd, const char *who, char *ip, 
-                                 int port, struct sockaddr_in *client_addr);
-BSOCK *    dup_bsock            (BSOCK *bsock);
-void      term_bsock            (BSOCK *bsock);
-char *    bnet_strerror         (BSOCK *bsock);
-char *    bnet_sig_to_ascii     (BSOCK *bsock);
-int       bnet_wait_data        (BSOCK *bsock, int sec);
-int       bnet_wait_data_intr   (BSOCK *bsock, int sec);
-int       bnet_despool_to_bsock (BSOCK *bsock);
-int       is_bnet_stop          (BSOCK *bsock);
-int       is_bnet_error         (BSOCK *bsock);
-void      bnet_suppress_error_messages(BSOCK *bsock, int flag);
+int32_t    bnet_recv             (BSOCK *bsock);
+int        bnet_send             (BSOCK *bsock);
+int        bnet_fsend            (BSOCK *bs, const char *fmt, ...);
+int        bnet_set_buffer_size  (BSOCK *bs, uint32_t size, int rw);
+int        bnet_sig              (BSOCK *bs, int sig);
+int        bnet_ssl_server       (BSOCK *bsock, char *password, int ssl_need, int ssl_has);
+int        bnet_ssl_client       (BSOCK *bsock, char *password, int ssl_need);
+BSOCK *    bnet_connect            (JCR *jcr, int retry_interval,
+               int max_retry_time, const char *name, char *host, char *service, 
+               int port, int verbose);
+void       bnet_close            (BSOCK *bsock);
+BSOCK *    init_bsock            (JCR *jcr, int sockfd, const char *who, char *ip, 
+                                  int port, struct sockaddr_in *client_addr);
+BSOCK *    dup_bsock             (BSOCK *bsock);
+void       term_bsock            (BSOCK *bsock);
+char *     bnet_strerror         (BSOCK *bsock);
+char *     bnet_sig_to_ascii     (BSOCK *bsock);
+int        bnet_wait_data        (BSOCK *bsock, int sec);
+int        bnet_wait_data_intr   (BSOCK *bsock, int sec);
+int        bnet_despool_to_bsock (BSOCK *bsock);
+int        is_bnet_stop          (BSOCK *bsock);
+int        is_bnet_error         (BSOCK *bsock);
+void       bnet_suppress_error_messages(BSOCK *bsock, int flag);
 
 /* bget_msg.c */
-int     bget_msg(BSOCK *sock);
+int      bget_msg(BSOCK *sock);
 
 /* bpipe.c */
-BPIPE *         open_bpipe(char *prog, int wait, const char *mode);
-int             close_wpipe(BPIPE *bpipe);
-int             close_bpipe(BPIPE *bpipe);
+BPIPE *          open_bpipe(char *prog, int wait, const char *mode);
+int              close_wpipe(BPIPE *bpipe);
+int              close_bpipe(BPIPE *bpipe);
 
 /* cram-md5.c */
 int cram_md5_get_auth(BSOCK *bs, char *password, int ssl_need);
 int cram_md5_auth(BSOCK *bs, char *password, int ssl_need);
 void hmac_md5(uint8_t* text, int text_len, uint8_t*  key,
-             int key_len, uint8_t *hmac);
+              int key_len, uint8_t *hmac);
 
 /* crc32.c */
 
 uint32_t bcrc32(uint8_t *buf, int len);
 
 /* daemon.c */
-void    daemon_start            ();
+void     daemon_start            ();
 
 /* edit.c */
-uint64_t        str_to_uint64(char *str);
-int64_t         str_to_int64(char *str);
-char *          edit_uint64_with_commas   (uint64_t val, char *buf);
-char *          add_commas              (char *val, char *buf);
-char *          edit_uint64             (uint64_t val, char *buf);
-int             duration_to_utime       (char *str, utime_t *value);
-int             size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
-char            *edit_utime             (utime_t val, char *buf);
-int             is_a_number             (const char *num);
-int             is_an_integer           (const char *n);
-bool            is_name_valid           (char *name, POOLMEM **msg);
+uint64_t         str_to_uint64(char *str);
+int64_t          str_to_int64(char *str);
+char *           edit_uint64_with_commas   (uint64_t val, char *buf);
+char *           add_commas              (char *val, char *buf);
+char *           edit_uint64             (uint64_t val, char *buf);
+int              duration_to_utime       (char *str, utime_t *value);
+int              size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
+char             *edit_utime             (utime_t val, char *buf);
+int              is_a_number             (const char *num);
+int              is_an_integer           (const char *n);
+bool             is_name_valid           (char *name, POOLMEM **msg);
 
 /* jcr.c (most definitions are in src/jcr.h) */
 void init_last_jobs_list();
@@ -132,38 +132,36 @@ void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr));
 
 
 /* lex.c */
-LEX *    lex_close_file         (LEX *lf);
-LEX *    lex_open_file          (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
-int      lex_get_char           (LEX *lf);
-void     lex_unget_char         (LEX *lf);
-const char *  lex_tok_to_str    (int token);
-int      lex_get_token          (LEX *lf, int expect);
+LEX *     lex_close_file         (LEX *lf);
+LEX *     lex_open_file          (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
+int       lex_get_char           (LEX *lf);
+void      lex_unget_char         (LEX *lf);
+const char *  lex_tok_to_str     (int token);
+int       lex_get_token          (LEX *lf, int expect);
 
 /* message.c */
-void      my_name_is            (int argc, char *argv[], const char *name);
-void      init_msg              (JCR *jcr, MSGS *msg);
-void      term_msg              (void);
-void      close_msg             (JCR *jcr);
-void      add_msg_dest          (MSGS *msg, int dest, int type, char *where, char *dest_code);
-void      rem_msg_dest          (MSGS *msg, int dest, int type, char *where);
-void      Jmsg                  (JCR *jcr, int type, int level, const char *fmt, ...);
-void      dispatch_message      (JCR *jcr, int type, int level, char *buf);
-void      init_console_msg      (char *wd);
-void      free_msgs_res         (MSGS *msgs);
-int       open_spool_file       (JCR *jcr, BSOCK *bs);
-int       close_spool_file      (JCR *jcr, BSOCK *bs);
-void      dequeue_messages      (JCR *jcr);
-void      set_trace             (int trace_flag);
+void       my_name_is            (int argc, char *argv[], const char *name);
+void       init_msg              (JCR *jcr, MSGS *msg);
+void       term_msg              (void);
+void       close_msg             (JCR *jcr);
+void       add_msg_dest          (MSGS *msg, int dest, int type, char *where, char *dest_code);
+void       rem_msg_dest          (MSGS *msg, int dest, int type, char *where);
+void       Jmsg                  (JCR *jcr, int type, int level, const char *fmt, ...);
+void       dispatch_message      (JCR *jcr, int type, int level, char *buf);
+void       init_console_msg      (char *wd);
+void       free_msgs_res         (MSGS *msgs);
+void       dequeue_messages      (JCR *jcr);
+void       set_trace             (int trace_flag);
 
 
 /* bnet_server.c */
-void      bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq, 
-                  void *handle_client_request(void *bsock));
-void      bnet_stop_thread_server(pthread_t tid);
-void            bnet_server             (int port, void handle_client_request(BSOCK *bsock));
-int             net_connect             (int port);
-BSOCK *         bnet_bind               (int port);
-BSOCK *         bnet_accept             (BSOCK *bsock, char *who);
+void       bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq, 
+                   void *handle_client_request(void *bsock));
+void       bnet_stop_thread_server(pthread_t tid);
+void             bnet_server             (int port, void handle_client_request(BSOCK *bsock));
+int              net_connect             (int port);
+BSOCK *          bnet_bind               (int port);
+BSOCK *          bnet_accept             (BSOCK *bsock, char *who);
 
 /* idcache.c */
 char *getuser(uid_t uid);
@@ -173,37 +171,37 @@ void free_getgroup_cache();
 
 
 /* signal.c */
-void            init_signals             (void terminate(int sig));
-void            init_stack_dump          (void);
+void             init_signals             (void terminate(int sig));
+void             init_stack_dump          (void);
 
 /* scan.c */
-void            strip_trailing_junk     (char *str);
-void            strip_trailing_slashes  (char *dir);
-bool            skip_spaces             (char **msg);
-bool            skip_nonspaces          (char **msg);
-int             fstrsch                 (char *a, char *b);
-int             parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, 
-                       char **argk, char **argv, int max_args);
-char           *next_arg(char **s);
+void             strip_trailing_junk     (char *str);
+void             strip_trailing_slashes  (char *dir);
+bool             skip_spaces             (char **msg);
+bool             skip_nonspaces          (char **msg);
+int              fstrsch                 (char *a, char *b);
+int              parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, 
+                        char **argk, char **argv, int max_args);
+char            *next_arg(char **s);
 
 /* util.c */
-int             is_buf_zero             (char *buf, int len);
-void            lcase                   (char *str);
-void            bash_spaces             (char *str);
-void            unbash_spaces           (char *str);
-char *          encode_time             (time_t time, char *buf);
-char *          encode_mode             (mode_t mode, char *buf);
-int             do_shell_expansion      (char *name, int name_len);
-void            jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
-int             pm_strcat               (POOLMEM **pm, const char *str);
-int             pm_strcpy               (POOLMEM **pm, const char *str);
-int             run_program             (char *prog, int wait, POOLMEM *results);
-char *          job_type_to_str         (int type);
-char *          job_status_to_str       (int stat);
-char *          job_level_to_str        (int level);
-void            make_session_key        (char *key, char *seed, int mode);
-POOLMEM        *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to);
-void            set_working_directory(char *wd);
+int              is_buf_zero             (char *buf, int len);
+void             lcase                   (char *str);
+void             bash_spaces             (char *str);
+void             unbash_spaces           (char *str);
+char *           encode_time             (time_t time, char *buf);
+char *           encode_mode             (mode_t mode, char *buf);
+int              do_shell_expansion      (char *name, int name_len);
+void             jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
+int              pm_strcat               (POOLMEM **pm, const char *str);
+int              pm_strcpy               (POOLMEM **pm, const char *str);
+int              run_program             (char *prog, int wait, POOLMEM *results);
+char *           job_type_to_str         (int type);
+char *           job_status_to_str       (int stat);
+char *           job_level_to_str        (int level);
+void             make_session_key        (char *key, char *seed, int mode);
+POOLMEM         *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to);
+void             set_working_directory(char *wd);
 
 
 /* watchdog.c */
index c3a57d55039c8d1fbe72c2b7c578223a1e83113b..8cafa06f253040359bde8feef5cb4d114fb37405 100644 (file)
@@ -42,6 +42,7 @@ DCR *new_dcr(JCR *jcr, DEVICE *dev)
    dcr->block = new_block(dev);
    dcr->record = new_record();
    dcr->spool_fd = -1;
+   dcr->max_spool_size = dev->device->max_spool_size;
    return dcr;
 }
 
@@ -129,7 +130,7 @@ DCR *acquire_device_for_read(JCR *jcr)
        */
       for ( ; !(dev->state & ST_OPENED); ) {
          Dmsg1(120, "bstored: open vol=%s\n", jcr->VolumeName);
-        if (open_dev(dev, dcr->VolumeName, READ_ONLY) < 0) {
+        if (open_dev(dev, dcr->VolumeName, OPEN_READ_ONLY) < 0) {
             Jmsg(jcr, M_FATAL, 0, _("Open device %s volume %s failed, ERR=%s\n"), 
                dev_name(dev), dcr->VolumeName, strerror_dev(dev));
            goto get_out;
index b22d6cad9fc4945aa3c91e4a8b9e4348ebcfd198..9375fd8f7cf7a813a5f77453b56ef298ac177afe 100644 (file)
@@ -205,17 +205,17 @@ int do_append_data(JCR *jcr)
             stream == STREAM_UNIX_ATTRIBUTES_EX || stream == STREAM_SHA1_SIGNATURE) { 
            if (!jcr->no_attributes) {
               if (are_attributes_spooled(jcr)) {
-                 jcr->dir_bsock->spool = 1;
+                 jcr->dir_bsock->spool = true;
               }
                Dmsg0(200, "Send attributes.\n");
               if (!dir_update_file_attributes(jcr, &rec)) {
+                 jcr->dir_bsock->spool = false;
                   Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
                     bnet_strerror(jcr->dir_bsock));
                  ok = false;
-                 jcr->dir_bsock->spool = 0;
                  break;
               }
-              jcr->dir_bsock->spool = 0;
+              jcr->dir_bsock->spool = false;
            }
         }
       }
index 7d334c2ea804a898b1f9a17911a0f9459a7a4962..98732aa2c3c9e4948ee12c67b65f48148dbc6f45 100644 (file)
@@ -154,7 +154,7 @@ int main (int argc, char *argv[])
    }
    /* For we must now acquire the device for writing */
    lock_device(out_dev);
-   if (open_dev(out_dev, out_jcr->VolumeName, READ_WRITE) < 0) {
+   if (open_dev(out_dev, out_jcr->VolumeName, OPEN_READ_WRITE) < 0) {
       Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), out_dev->errmsg);
       unlock_device(out_dev);
       exit(1);
index f04cbd93e734b14a152d2c3d08ef4d2b3a305f8d..afb880c585960f32b1241f1c47325430de3df20f 100644 (file)
@@ -322,7 +322,9 @@ int write_block_to_device(DCR *dcr, DEV_BLOCK *block)
       return stat;
    }
 
-   lock_device(dev);
+   if (!dcr->dev_locked) {
+      lock_device(dev);
+   }
 
    /*
     * If a new volume has been mounted since our last write
@@ -336,8 +338,8 @@ int write_block_to_device(DCR *dcr, DEV_BLOCK *block)
          Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
            jcr->VolCatInfo.VolCatName, jcr->Job);
         set_new_volume_parameters(jcr, dev);
-        unlock_device(dev);
-        return 0;
+        stat = 0;
+        goto bail_out;
       }
       if (dcr->NewVol) {
         /* Note, setting a new volume also handles any pending new file */
@@ -352,7 +354,10 @@ int write_block_to_device(DCR *dcr, DEV_BLOCK *block)
        stat = fixup_device_block_write_error(jcr, dev, block);
    }
 
-   unlock_device(dev);
+bail_out:
+   if (!dcr->dev_locked) {
+      unlock_device(dev);
+   }
    return stat;
 }
 
index ac7f24f2bea67fef914884e288d0971733f2b181..408d6dd41a7279b3d2bc9c296d5a1bff3a75f02c 100644 (file)
@@ -295,7 +295,7 @@ static bool open_the_device()
    lock_device(dev);
    if (!(dev->state & ST_OPENED)) {
       Dmsg1(200, "Opening device %s\n", jcr->VolumeName);
-      if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
+      if (open_dev(dev, jcr->VolumeName, OPEN_READ_WRITE) < 0) {
          Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
         unlock_device(dev);
         free_block(block);
index 8a8965116b822644ee4a6f8e534e8926e28e0f55..2a208dd709d47ec89d3e3aa682af6c0d41f45287 100644 (file)
@@ -2,7 +2,7 @@
  *
  *   dev.c  -- low level operations on device (storage device)
  *
- *             Kern Sibbald
+ *             Kern Sibbald, MM 
  *
  *     NOTE!!!! None of these routines are reentrant. You must
  *       use lock_device() and unlock_device() at a higher level,
  * to include ST_EOT, which is ephimeral, and ST_WEOT, which is
  * persistent. Lots of routines clear ST_EOT, but ST_WEOT is
  * cleared only when the problem goes away.  Now when ST_WEOT
- * is set all calls to write_dev() are handled as usual. However,
- * in write_block() instead of attempting to write the block to
- * the physical device, it is chained into a list of blocks written
- * after the EOT condition.  In addition, all threads are blocked
- * from writing on the tape by calling lock(), and thread other
+ * is set all calls to write_block_to_device() call the fix_up
+ * routine. In addition, all threads are blocked
+ * from writing on the tape by calling lock_dev(), and thread other
  * than the first thread to hit the EOT will block on a condition
  * variable. The first thread to hit the EOT will continue to
  * be able to read and write the tape (he sort of tunnels through
- * the locking mechanism -- see lock() for details).
+ * the locking mechanism -- see lock_dev() for details).
  *
  * Now presumably somewhere higher in the chain of command 
  * (device.c), someone will notice the EOT condition and 
@@ -149,6 +147,7 @@ init_dev(DEVICE *dev, DEVRES *device)
    dev->max_open_wait = device->max_open_wait;
    dev->max_open_vols = device->max_open_vols;
    dev->vol_poll_interval = device->vol_poll_interval;
+   dev->max_spool_size = device->max_spool_size;
    /* Sanity check */
    if (dev->vol_poll_interval && dev->vol_poll_interval < 60) {
       dev->vol_poll_interval = 60;
@@ -192,6 +191,11 @@ init_dev(DEVICE *dev, DEVRES *device)
       Mmsg1(&dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
+   if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) {
+      dev->dev_errno = errstat;
+      Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
+      Emsg0(M_FATAL, 0, dev->errmsg);
+   }
    dev->fd = -1;
    dev->attached_dcrs = new dlist(dcr, &dcr->dev_link);
    Dmsg2(29, "init_dev: tape=%d dev_name=%s\n", dev_is_tape(dev), dev->dev_name);
@@ -1391,6 +1395,7 @@ term_dev(DEVICE *dev)
    pthread_mutex_destroy(&dev->mutex);
    pthread_cond_destroy(&dev->wait);
    pthread_cond_destroy(&dev->wait_next_vol);
+   pthread_mutex_destroy(&dev->spool_mutex);
    if (dev->attached_dcrs) {
       delete dev->attached_dcrs;
       dev->attached_dcrs = NULL;
index a48d93d5387cb6ed3dcdb4780078473407f7a424..f43a5bc1bbd0abd17d91f6cb326d50ccecebd1cb 100644 (file)
 #define give_back_device_lock(d, p) _give_back_device_lock(__FILE__, __LINE__, (d), (p))
 
 /* Arguments to open_dev() */
-#define READ_WRITE       0
-#define READ_ONLY        1
-#define OPEN_READ_WRITE  0
-#define OPEN_READ_ONLY   1
-#define OPEN_WRITE_ONLY  2
+enum {
+   OPEN_READ_WRITE = 0,
+   OPEN_READ_ONLY,
+   OPEN_WRITE_ONLY   
+};
 
 /* Generic status bits returned from status_dev() */
 #define BMT_TAPE           (1<<0)     /* is tape device */
 #define ST_SHORT           (1<<13)    /* Short block read */
 
 /* dev_blocked states (mutually exclusive) */
-#define BST_NOT_BLOCKED       0       /* not blocked */
-#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 */  
-#define BST_UNMOUNTED_WAITING_FOR_SYSOP 5 /* Closed by user during mount request */
-#define BST_MOUNT             6       /* Mount request */
+enum {
+   BST_NOT_BLOCKED = 0,               /* not blocked */
+   BST_UNMOUNTED,                     /* User unmounted device */
+   BST_WAITING_FOR_SYSOP,             /* Waiting for operator to mount tape */
+   BST_DOING_ACQUIRE,                 /* Opening/validating/moving tape */
+   BST_WRITING_LABEL,                  /* Labeling a tape */  
+   BST_UNMOUNTED_WAITING_FOR_SYSOP,    /* Closed by user during mount request */
+   BST_MOUNT                           /* Mount request */
+};
 
 /* Volume Catalog Information structure definition */
 struct VOLUME_CAT_INFO {
@@ -141,9 +143,9 @@ struct VOLUME_CAT_INFO {
 
 
 typedef struct s_steal_lock {
-   pthread_t         no_wait_id;      /* id of no wait thread */
-   int               dev_blocked;     /* state */
-   int               dev_prev_blocked; /* previous blocked state */
+   pthread_t  no_wait_id;             /* id of no wait thread */
+   int        dev_blocked;            /* state */
+   int        dev_prev_blocked;       /* previous blocked state */
 } bsteal_lock_t;
 
 struct DEVRES;                        /* Device resource defined in stored_conf.h */
@@ -160,6 +162,7 @@ public:
    JCR *attached_jcrs;                /* attached JCR list */
    dlist *attached_dcrs;              /* attached DCR list */
    pthread_mutex_t mutex;             /* access control */
+   pthread_mutex_t spool_mutex;       /* mutex for updating spool_size */
    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 */
@@ -186,6 +189,8 @@ public:
    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 */
+   uint64_t max_spool_size;           /* maximum spool file size */
+   uint64_t spool_size;               /* curren spool size */
    uint32_t max_rewind_wait;          /* max secs to allow for rewind */
    uint32_t max_open_wait;            /* max secs to allow for open */
    uint32_t max_open_vols;            /* max simultaneous open volumes */
@@ -221,6 +226,7 @@ struct DCR {
    DEV_RECORD *record;                /* pointer to record */
    bool spool_data;                   /* set to spool data */
    bool spooling;                     /* set when actually spooling */
+   bool dev_locked;                   /* set if dev already locked */
    int spool_fd;                      /* fd if spooling */
    bool NewVol;                       /* set if new Volume mounted */
    bool WroteVol;                     /* set if Volume written */
@@ -232,6 +238,8 @@ struct DCR {
    uint32_t StartFile;                /* Start write file */
    uint32_t StartBlock;               /* Start write block */
    uint32_t EndBlock;                 /* Ending block written */
+   uint64_t spool_size;               /* Current spool size */
+   uint64_t max_spool_size;           /* Max job spool size */
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
    VOLUME_CAT_INFO VolCatInfo;        /* Catalog info for desired volume */
 };
index bd309d569403ae305fde2eef343b0499f5e3ac2b..1ec7d09b19f8cb864255d9d9861dbbd5f5d813d3 100644 (file)
@@ -362,7 +362,7 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
 
    /* Ensure that the device is open -- autoload_device() closes it */
    for ( ; !(dev->state & ST_OPENED); ) {
-      if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
+      if (open_dev(dev, jcr->VolumeName, OPEN_READ_WRITE) < 0) {
          bnet_fsend(dir, _("3910 Unable to open device %s. ERR=%s\n"), 
            dev_name(dev), strerror_dev(dev));
         goto bail_out;
@@ -498,7 +498,7 @@ static int mount_cmd(JCR *jcr)
         case BST_UNMOUNTED_WAITING_FOR_SYSOP:
         case BST_UNMOUNTED:
            /* We freed the device, so reopen it and wake any waiting threads */
-           if (open_dev(dev, NULL, READ_WRITE) < 0) {
+           if (open_dev(dev, NULL, OPEN_READ_WRITE) < 0) {
                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"), 
                  strerror_dev(dev));
               break;
@@ -550,7 +550,7 @@ static int mount_cmd(JCR *jcr)
                   bnet_fsend(dir, _("3906 cannot mount non-tape.\n"));
                  break;
               }
-              if (open_dev(dev, NULL, READ_WRITE) < 0) {
+              if (open_dev(dev, NULL, OPEN_READ_WRITE) < 0) {
                   bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"), 
                     strerror_dev(dev));
                  break;
@@ -838,7 +838,7 @@ static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
 
    /* Ensure that the device is open -- autoload_device() closes it */
    for ( ; !dev_state(dev, ST_OPENED); ) {
-      if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
+      if (open_dev(dev, jcr->VolumeName, OPEN_READ_WRITE) < 0) {
          bnet_fsend(dir, _("3910 Unable to open device \"%s\". ERR=%s\n"), 
            dev_name(dev), strerror_dev(dev));
         goto bail_out;
index 8c25d835455fb5bd8fc89f5eea9cf70ac4941d7f..4fd66f71f50e05652800346a5569bf746e8fe312 100644 (file)
@@ -200,11 +200,13 @@ int read_records(JCR *jcr,  DEVICE *dev,
        int mount_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block));
 
 /* From spool.c */
-int begin_data_spool(JCR *jcr);
-int discard_data_spool(JCR *jcr);
-int commit_data_spool(JCR *jcr);
-bool are_attributes_spooled(JCR *jcr);
-int begin_attribute_spool(JCR *jcr);
-int discard_attribute_spool(JCR *jcr);
-int commit_attribute_spool(JCR *jcr);
-bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block);
+bool   begin_data_spool          (JCR *jcr);
+bool   discard_data_spool        (JCR *jcr);
+bool   commit_data_spool         (JCR *jcr);
+bool   are_attributes_spooled    (JCR *jcr);
+bool   begin_attribute_spool     (JCR *jcr);
+bool   discard_attribute_spool   (JCR *jcr);
+bool   commit_attribute_spool    (JCR *jcr);
+bool   write_block_to_spool_file (DCR *dcr, DEV_BLOCK *block);
+bool   open_spool_file           (JCR *jcr, BSOCK *bs);
+bool   close_spool_file          (JCR *jcr, BSOCK *bs);
index 3f1aefe67fd599cd460bc0b92762b49ea961a0fc..b9f6942a376cb29a44938576dec7173b2acdf8a2 100644 (file)
@@ -47,9 +47,9 @@ enum {
    RB_OK
 };
 
-int begin_data_spool(JCR *jcr)
+bool begin_data_spool(JCR *jcr)
 {
-   int stat = 1;
+   bool stat = true;
    if (jcr->spool_data) {
       Dmsg0(100, "Turning on data spooling\n");
       jcr->dcr->spool_data = true;
@@ -61,16 +61,16 @@ int begin_data_spool(JCR *jcr)
    return stat;
 }
 
-int discard_data_spool(JCR *jcr)
+bool discard_data_spool(JCR *jcr)
 {
    if (jcr->dcr->spooling) {
       Dmsg0(100, "Data spooling discarded\n");
       return close_data_spool_file(jcr);
    }
-   return 1;
+   return true;
 }
 
-int commit_data_spool(JCR *jcr)
+bool commit_data_spool(JCR *jcr)
 {
    bool stat;
    if (jcr->dcr->spooling) {
@@ -79,17 +79,22 @@ int commit_data_spool(JCR *jcr)
       if (!stat) {
          Dmsg1(000, "Bad return from despool WroteVol=%d\n", jcr->dcr->WroteVol);
         close_data_spool_file(jcr);
-        return 0;
+        return false;
       }
       return close_data_spool_file(jcr);
    }
-   return 1;
+   return true;
 }
 
 static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name)
 {
-   Mmsg(name, "%s/%s.data.spool.%s.%s", working_directory, my_name,
-      jcr->Job, jcr->device->hdr.name);
+   char *dir;  
+   if (jcr->dcr->dev->device->spool_directory) {
+      dir = jcr->dcr->dev->device->spool_directory;
+   } else {
+      dir = working_directory;
+   }
+   Mmsg(name, "%s/%s.data.spool.%s.%s", dir, my_name, jcr->Job, jcr->device->hdr.name);
 }
 
 
@@ -130,13 +135,14 @@ static bool despool_data(DCR *dcr)
 {
    DEVICE *rdev;
    DCR *rdcr;
-   dcr->spooling = false;
    bool ok = true;
    DEV_BLOCK *block;
    JCR *jcr = dcr->jcr;
    int stat;
 
-// lock_device(dcr->dev);
+   dcr->spooling = false;
+   lock_device(dcr->dev);
+   dcr->dev_locked = true; 
    Dmsg0(100, "Despooling data\n");
    /* Set up a dev structure to read */
    rdev = (DEVICE *)malloc(sizeof(DEVICE));
@@ -145,6 +151,7 @@ static bool despool_data(DCR *dcr)
    strcpy(rdev->dev_name, "spool");
    rdev->errmsg = get_pool_memory(PM_EMSG);
    *rdev->errmsg = 0;
+   rdev->device = dcr->dev->device;
    rdcr = new_dcr(NULL, rdev);
    rdcr->spool_fd = dcr->spool_fd; 
    rdcr->jcr = jcr;                  /* set a valid jcr */
@@ -170,12 +177,19 @@ static bool despool_data(DCR *dcr)
       Dmsg1(000, "Bad return from ftruncate. ERR=%s\n", strerror(errno));
       ok = false;
    }
+
+   P(dcr->dev->spool_mutex);
+   dcr->dev->spool_size -= dcr->spool_size;
+   dcr->spool_size = 0;              /* zap size in input dcr */
+   V(dcr->dev->spool_mutex);
+
    free_memory(rdev->dev_name);
    free_pool_memory(rdev->errmsg);
    free(rdev);
    rdcr->jcr = NULL;
    free_dcr(rdcr);
-// unlock_device(dcr->dev);
+   unlock_device(dcr->dev);
+   dcr->dev_locked = false;
    return ok;
 }
 
@@ -238,12 +252,31 @@ static int read_block_from_spool_file(DCR *dcr, DEV_BLOCK *block)
 bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
 {
    ssize_t stat = 0;
-   uint32_t wlen;                    /* length to write */
+   uint32_t wlen, hlen;              /* length to write */
    int retry = 0;
    spool_hdr hdr;   
+   bool despool = false;
 
    ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
-
+   hlen = sizeof(hdr);
+   wlen = block->binbuf;
+   P(dcr->dev->spool_mutex);
+   dcr->spool_size += hlen + wlen;
+   dcr->dev->spool_size += hlen + wlen;
+   if ((dcr->max_spool_size > 0 && dcr->spool_size >= dcr->max_spool_size) ||
+       (dcr->dev->spool_size > 0 && dcr->dev->spool_size >= dcr->dev->max_spool_size)) {
+      despool = true;
+   }
+   V(dcr->dev->spool_mutex);
+   if (despool) {
+      if (!despool_data(dcr)) {
+        return false;
+      }
+      P(dcr->dev->spool_mutex);
+      dcr->spool_size += hlen + wlen;
+      dcr->dev->spool_size += hlen + wlen;
+      V(dcr->dev->spool_mutex);
+   }  
    if (block->binbuf <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */
       Dmsg0(100, "return write_block_to_dev no data to write\n");
       return true;
@@ -252,10 +285,9 @@ bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
    hdr.FirstIndex = block->FirstIndex;
    hdr.LastIndex = block->LastIndex;
    hdr.len = block->binbuf;
-   wlen = sizeof(hdr);
 write_hdr_again:
-   stat = write(dcr->spool_fd, (char*)&hdr, (size_t)wlen);
-   if (stat != (ssize_t)wlen) {
+   stat = write(dcr->spool_fd, (char*)&hdr, (size_t)hlen);
+   if (stat != (ssize_t)hlen) {
       if (!despool_data(dcr)) {
         return false;
       }
@@ -266,7 +298,6 @@ write_hdr_again:
    }
 
 
-   wlen = block->binbuf;
    Dmsg2(300, "Wrote block FI=%d LI=%d\n", block->FirstIndex, block->LastIndex);
 write_again:
    stat = write(dcr->spool_fd, block->buf, (size_t)wlen);
@@ -280,38 +311,79 @@ write_again:
       goto write_again;
    }
 
+
    empty_block(block);
    return true;
 }
 
 
-
 bool are_attributes_spooled(JCR *jcr)
 {
    return jcr->spool_attributes && jcr->dir_bsock->spool_fd;
 }
 
-int begin_attribute_spool(JCR *jcr)
+/* 
+ * Create spool file for attributes.
+ *  This is done by "attaching" to the bsock, and when
+ *  it is called, the output is written to a file.
+ *  The actual spooling is turned on and off in
+ *  append.c only during writing of the attributes.
+ */
+bool begin_attribute_spool(JCR *jcr)
 {
    if (!jcr->no_attributes && jcr->spool_attributes) {
       return open_spool_file(jcr, jcr->dir_bsock);
    }
-   return 1;
+   return true;
 }
 
-int discard_attribute_spool(JCR *jcr)
+bool discard_attribute_spool(JCR *jcr)
 {
    if (are_attributes_spooled(jcr)) {
       return close_spool_file(jcr, jcr->dir_bsock);
    }
-   return 1;
+   return true;
 }
 
-int commit_attribute_spool(JCR *jcr)
+bool commit_attribute_spool(JCR *jcr)
 {
    if (are_attributes_spooled(jcr)) {
       bnet_despool_to_bsock(jcr->dir_bsock);
       return close_spool_file(jcr, jcr->dir_bsock);
    }
-   return 1;
+   return true;
+}
+
+static void make_unique_spool_filename(JCR *jcr, POOLMEM **name, int fd)
+{
+   Mmsg(name, "%s/%s.spool.%s.%d", working_directory, my_name,
+      jcr->Job, fd);
+}
+
+bool open_spool_file(JCR *jcr, BSOCK *bs)
+{
+    POOLMEM *name  = get_pool_memory(PM_MESSAGE);
+
+    make_unique_spool_filename(jcr, &name, bs->fd);
+    bs->spool_fd = fopen(mp_chr(name), "w+");
+    if (!bs->spool_fd) {
+       Jmsg(jcr, M_ERROR, 0, "fopen spool file %s failed: ERR=%s\n", name, strerror(errno));
+       free_pool_memory(name);
+       return false;
+    }
+    free_pool_memory(name);
+    return true;
+}
+
+bool close_spool_file(JCR *jcr, BSOCK *bs)
+{
+    POOLMEM *name  = get_pool_memory(PM_MESSAGE);
+
+    make_unique_spool_filename(jcr, &name, bs->fd);
+    fclose(bs->spool_fd);
+    unlink(mp_chr(name));
+    free_pool_memory(name);
+    bs->spool_fd = NULL;
+    bs->spool = false;
+    return true;
 }
index 5916143e6d67fd0853c32ab7938f5dc7ac41c3aa..f29bd0a0279b1e8aee15c7c3f0104677360aacfa 100644 (file)
@@ -114,6 +114,9 @@ static RES_ITEM dev_items[] = {
    {"maximumvolumesize",     store_size,   ITEM(res_dev.max_volume_size), 0, 0, 0},
    {"maximumfilesize",       store_size,   ITEM(res_dev.max_file_size), 0, ITEM_DEFAULT, 1000000000},
    {"volumecapacity",        store_size,   ITEM(res_dev.volume_capacity), 0, 0, 0},
+   {"spooldirectory",        store_dir,    ITEM(res_dev.spool_directory), 0, 0, 0},
+   {"maximumspoolsize",      store_size,   ITEM(res_dev.max_spool_size), 0, 0, 0},
+   {"maximumjobspoolsize",   store_size,   ITEM(res_dev.max_job_spool_size), 0, 0, 0},
    {NULL, NULL, 0, 0, 0, 0} 
 };
 
@@ -130,7 +133,7 @@ RES_TABLE resources[] = {
    {"storage",       store_items, R_STORAGE,   NULL},
    {"device",        dev_items,   R_DEVICE,    NULL},
    {"messages",      msgs_items,  R_MSGS,      NULL},
-   {NULL,           NULL,        0,           NULL}
+   {NULL,            NULL,        0,           NULL}
 };
 
 
@@ -146,7 +149,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       return;
    }
    sendit(sock, "dump_resource type=%d\n", type);
-   if (type < 0) {                   /* no recursion */
+   if (type < 0) {                    /* no recursion */
       type = - type;
       recurse = 0;
    }
@@ -156,22 +159,25 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       break;
    case R_STORAGE:
       sendit(sock, "Storage: name=%s SDaddr=%s SDport=%d SDDport=%d HB=%s\n",
-        res->res_store.hdr.name, NPRT(res->res_store.SDaddr),
-        res->res_store.SDport, res->res_store.SDDport,
-        edit_utime(res->res_store.heartbeat_interval, buf));
+         res->res_store.hdr.name, NPRT(res->res_store.SDaddr),
+         res->res_store.SDport, res->res_store.SDDport,
+         edit_utime(res->res_store.heartbeat_interval, buf));
       break;
    case R_DEVICE:
       sendit(sock, "Device: name=%s MediaType=%s Device=%s\n",
-        res->res_dev.hdr.name,
-        res->res_dev.media_type, res->res_dev.device_name);
+         res->res_dev.hdr.name,
+         res->res_dev.media_type, res->res_dev.device_name);
       sendit(sock, "        rew_wait=%d min_bs=%d max_bs=%d\n",
-        res->res_dev.max_rewind_wait, res->res_dev.min_block_size, 
-        res->res_dev.max_block_size);
+         res->res_dev.max_rewind_wait, res->res_dev.min_block_size, 
+         res->res_dev.max_block_size);
       sendit(sock, "        max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-        res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-        res->res_dev.max_volume_size);
+         res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
+         res->res_dev.max_volume_size);
       sendit(sock, "        max_file_size=%" lld " capacity=%" lld "\n",
-        res->res_dev.max_file_size, res->res_dev.volume_capacity);
+         res->res_dev.max_file_size, res->res_dev.volume_capacity);
+      sendit(sock, "         spool_directory=%s\n", res->res_dev.spool_directory);
+      sendit(sock, "         max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
+         res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
       strcpy(buf, "        ");
       if (res->res_dev.cap_bits & CAP_EOF) {
          bstrncat(buf, "CAP_EOF ", sizeof(buf));
@@ -254,57 +260,60 @@ void free_resource(RES *sres, int type)
 
    switch (type) {
       case R_DIRECTOR:
-        if (res->res_dir.password) {
-           free(res->res_dir.password);
-        }
-        if (res->res_dir.address) {
-           free(res->res_dir.address);
-        }
-        break;
+         if (res->res_dir.password) {
+            free(res->res_dir.password);
+         }
+         if (res->res_dir.address) {
+            free(res->res_dir.address);
+         }
+         break;
       case R_STORAGE:
-        if (res->res_store.address) {  /* ***FIXME*** deprecated */
-           free(res->res_store.address);
-        }
-        if (res->res_store.SDaddr) {
-           free(res->res_store.SDaddr);
-        }
-        if (res->res_store.working_directory) {
-           free(res->res_store.working_directory);
-        }
-        if (res->res_store.pid_directory) {
-           free(res->res_store.pid_directory);
-        }
-        if (res->res_store.subsys_directory) {
-           free(res->res_store.subsys_directory);
-        }
-        break;
+         if (res->res_store.address) {  /* ***FIXME*** deprecated */
+            free(res->res_store.address);
+         }
+         if (res->res_store.SDaddr) {
+            free(res->res_store.SDaddr);
+         }
+         if (res->res_store.working_directory) {
+            free(res->res_store.working_directory);
+         }
+         if (res->res_store.pid_directory) {
+            free(res->res_store.pid_directory);
+         }
+         if (res->res_store.subsys_directory) {
+            free(res->res_store.subsys_directory);
+         }
+         break;
       case R_DEVICE:
-        if (res->res_dev.media_type) {
-           free(res->res_dev.media_type);
-        }
-        if (res->res_dev.device_name) {
-           free(res->res_dev.device_name);
-        }
-        if (res->res_dev.changer_name) {
-           free(res->res_dev.changer_name);
-        }
-        if (res->res_dev.changer_command) {
-           free(res->res_dev.changer_command);
-        }
-        break;
+         if (res->res_dev.media_type) {
+            free(res->res_dev.media_type);
+         }
+         if (res->res_dev.device_name) {
+            free(res->res_dev.device_name);
+         }
+         if (res->res_dev.changer_name) {
+            free(res->res_dev.changer_name);
+         }
+         if (res->res_dev.changer_command) {
+            free(res->res_dev.changer_command);
+         }
+         if (res->res_dev.spool_directory) {
+            free(res->res_dev.spool_directory);
+         }
+         break;
       case R_MSGS:
-        if (res->res_msgs.mail_cmd) {
-           free(res->res_msgs.mail_cmd);
-        }
-        if (res->res_msgs.operator_cmd) {
-           free(res->res_msgs.operator_cmd);
-        }
-        free_msgs_res((MSGS *)res);  /* free message resource */
-        res = NULL;
-        break;
+         if (res->res_msgs.mail_cmd) {
+            free(res->res_msgs.mail_cmd);
+         }
+         if (res->res_msgs.operator_cmd) {
+            free(res->res_msgs.operator_cmd);
+         }
+         free_msgs_res((MSGS *)res);  /* free message resource */
+         res = NULL;
+         break;
       default:
          Dmsg1(0, "Unknown resource type %d\n", type);
-        break;
+         break;
    }
    /* Common stuff again -- free the resource, recurse to next one */
    if (res) {
@@ -331,10 +340,10 @@ void save_resource(int type, RES_ITEM *items, int pass)
     */
    for (i=0; items[i].name; i++) {
       if (items[i].flags & ITEM_REQUIRED) {
-        if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
+         if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
             Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"),
-             items[i].name, resources[rindex]);
-         }
+              items[i].name, resources[rindex]);
+          }
       }
       /* If this triggers, take a look at lib/parse_conf.h */
       if (i >= MAX_RES_ITEMS) {
@@ -349,33 +358,33 @@ void save_resource(int type, RES_ITEM *items, int pass)
     */
    if (pass == 2) {
       switch (type) {
-        /* Resources not containing a resource */
-        case R_DIRECTOR:
-        case R_DEVICE:
-        case R_MSGS:
-           break;
-
-        /* Resources containing a resource */
-        case R_STORAGE:
-           if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
+         /* Resources not containing a resource */
+         case R_DIRECTOR:
+         case R_DEVICE:
+         case R_MSGS:
+            break;
+
+         /* Resources containing a resource */
+         case R_STORAGE:
+            if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
                Emsg1(M_ABORT, 0, "Cannot find Storage resource %s\n", res_all.res_dir.hdr.name);
-           }
-           res->res_store.messages = res_all.res_store.messages;
-           break;
-        default:
+            }
+            res->res_store.messages = res_all.res_store.messages;
+            break;
+         default:
             printf("Unknown resource type %d\n", type);
-           error = 1;
-           break;
+            error = 1;
+            break;
       }
 
 
       if (res_all.res_dir.hdr.name) {
-        free(res_all.res_dir.hdr.name);
-        res_all.res_dir.hdr.name = NULL;
+         free(res_all.res_dir.hdr.name);
+         res_all.res_dir.hdr.name = NULL;
       }
       if (res_all.res_dir.hdr.desc) {
-        free(res_all.res_dir.hdr.desc);
-        res_all.res_dir.hdr.desc = NULL;
+         free(res_all.res_dir.hdr.desc);
+         res_all.res_dir.hdr.desc = NULL;
       }
       return;
    }
@@ -383,42 +392,42 @@ void save_resource(int type, RES_ITEM *items, int pass)
    /* The following code is only executed on pass 1 */
    switch (type) {
       case R_DIRECTOR:
-        size = sizeof(DIRRES);
-        break;
+         size = sizeof(DIRRES);
+         break;
       case R_STORAGE:
-        size = sizeof(STORES);
-        break;
+         size = sizeof(STORES);
+         break;
       case R_DEVICE:
-        size = sizeof(DEVRES);
-        break;
+         size = sizeof(DEVRES);
+         break;
       case R_MSGS:
-        size = sizeof(MSGS);   
-        break;
+         size = sizeof(MSGS);   
+         break;
       default:
          printf("Unknown resource type %d\n", type);
-        error = 1;
-        size = 1;
-        break;
+         error = 1;
+         size = 1;
+         break;
    }
    /* Common */
    if (!error) {
       res = (URES *)malloc(size);
       memcpy(res, &res_all, size);
       if (!resources[rindex].res_head) {
-        resources[rindex].res_head = (RES *)res; /* store first entry */
+         resources[rindex].res_head = (RES *)res; /* store first entry */
       } else {
-        RES *next;
-        /* Add new res to end of chain */
-        for (next=resources[rindex].res_head; next->next; next=next->next) {
-           if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
-              Emsg2(M_ERROR_TERM, 0,
+         RES *next;
+         /* Add new res to end of chain */
+         for (next=resources[rindex].res_head; next->next; next=next->next) {
+            if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
+               Emsg2(M_ERROR_TERM, 0,
                   _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
-                 resources[rindex].name, res->res_dir.hdr.name);
-           }
-        }
-        next->next = (RES *)res;
+                  resources[rindex].name, res->res_dir.hdr.name);
+            }
+         }
+         next->next = (RES *)res;
          Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
-              res->res_dir.hdr.name);
+               res->res_dir.hdr.name);
       }
    }
 }
index 05a9c6d3255e526618ae97b797ccbbc55b947a4e..56e3aa60f39a472fb54725c016ac6bf51dd20842 100644 (file)
 
  */
 
-#define R_FIRST                       3001
-
-#define R_DIRECTOR                    3001
-#define R_STORAGE                     3002
-#define R_DEVICE                      3003
-#define R_MSGS                        3004
-
-#define R_LAST                        R_MSGS
-
+enum {
+   R_DIRECTOR = 3001,
+   R_STORAGE,
+   R_DEVICE,
+   R_MSGS,
+   R_FIRST = R_DIRECTOR,
+   R_LAST  = R_MSGS                   /* keep this updated */
+};
 
-#define R_NAME                        3020
-#define R_ADDRESS                     3021
-#define R_PASSWORD                    3022
-#define R_TYPE                        3023
-#define R_BACKUP                      3024
+enum {
+   R_NAME = 3020,
+   R_ADDRESS,
+   R_PASSWORD,
+   R_TYPE,
+   R_BACKUP
+};
 
 /* Definition of the contents of each Resource */
 struct DIRRES {
@@ -75,6 +76,7 @@ struct DEVRES {
    char *device_name;                 /* Archive device name */
    char *changer_name;                /* Changer device name */
    char *changer_command;             /* Changer command  -- external program */
+   char *spool_directory;             /* Spool file directory */
    uint32_t cap_bits;                 /* Capabilities of this device */
    uint32_t max_changer_wait;         /* Changer timeout */
    uint32_t max_rewind_wait;          /* maximum secs to wait for rewind */
@@ -89,6 +91,8 @@ struct DEVRES {
    int64_t max_volume_size;           /* max bytes to put on one volume */
    int64_t max_file_size;             /* max file size in bytes */
    int64_t volume_capacity;           /* advisory capacity */
+   int64_t max_spool_size;            /* Max spool size for all jobs */
+   int64_t max_job_spool_size;        /* Max spool size for any single job */
    DEVICE *dev;                       /* Pointer to phyical dev -- set at runtime */
 };
 
index 0f407c0dd23655ae8693cf60cf77c59133f06aa0..8a57e22b5a12670a7a9ec4a8d3e53f692d731d56 100644 (file)
@@ -2,8 +2,8 @@
 #undef  VERSION
 #define VERSION "1.33.4"
 #define VSTRING "1"
-#define BDATE   "09 Mar 2004"
-#define LSMDATE "09Mar04"
+#define BDATE   "10 Mar 2004"
+#define LSMDATE "10Mar04"
 
 /* Debug flags */
 #undef  DEBUG