Kern's ToDo List
- 22 February 2005
+ 07 March 2005
Major development:
Project Developer
#3 Migration (Move, Copy, Archive Jobs)
#4 Embedded Python Scripting
(Implemented in Dir/SD)
-#5 Events that call a Python program
- (Implemented in Dir/SD)
-#6 Select one from among Multiple Storage Devices for Job
#7 Single Job Writing to Multiple Storage Devices
## Integrate web-bacula into a new Bacula project with
bimagemgr.
## Consider moving docs to their own project.
-Suggestions for Preben:
-- Look at adding Client run command that will use the
- port opened by the client.
-- Optimized bootstrap.
-
Autochangers:
-- Fix
- Please use the "label" command to create a new Volume for:
- Storage: DDS-4-changer
- Media type:
- Pool: Default
- label
- The defined Storage resources are:
-- Copy Changer Device and Changer Command from Autochanger
- to Device resource in SD if none given in Device resource.
-- 3.Prevent two drives requesting the same Volume in any given
+- 3. Prevent two drives requesting the same Volume in any given
autochanger.
-- 4. Use Changer Device and Changer Command specified in the
- Autochanger resource, if none is found in the Device resource.
- You can continue to specify them in the Device resource if you want
- or need them to be different for each device.
-- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
- that can allow a Device be part of an Autochanger, and hence the changer
- script protected, but if set to no, will prevent the Device from being
- automatically selected from the changer. This allows the device to
- be directly accessed through its Device name, but not through the
- AutoChanger name.
+- 3. Check if a Volume is mounted on another drive in an Autochanger.
- 7. Implement new Console commands to allow offlining/reserving drives,
and possibly manipulating the autochanger (much asked for).
- 8. Automatic updating of Drive status from SD to DIR when something
changes (Volume, offline, append, read, ...).
-- 9. Check if a Volume is mounted on another drive in an Autochanger.
-
-Autochangers Done:
-- 1. Automatic use of more than one drive in an autochanger (done)
-- 2. Automatic selection of the correct drive for each Job (i.e.
- selects a drive with an appropriate Volume for the Job) (done)
-- 6. Allow multiple simultaneous Jobs referencing the same pool write
- to several tapes (some new directive(s) are are probably needed for
- this) (done)
-- Locking (done)
-- Key on Storage rather than Pool (done)
-- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
-- Synchronize multiple drives so that not more
- than one loads a tape and any time (done)
-
-
For 1.37:
+- Add disk seeking on restore.
+- Don't start a second file job if one is already running.
+- Add Python writable variable for changing the Priority,
+ Client, Storage, JobStatus (error), ...
+- SD Python
+ - Solicit Events
+- FD Python
+ - Python script to save with Python, not save, save with Bacula.
+ - Python script to do backup.
+- When Python creates a new label, the tape is immediately
+ recycled and no label created. This happens when using
+ autolabeling -- even when Python doesn't generate the name.
+- Create a new GUI chapter explaining all the GUI programs.
+- Look at Preben's acl.c error handling code.
+- Look at adding full Volume and Pool information to a Volume
+ label so that bscan can get *all* the info.
+- Scratch Pool where the volumes can be re-assigned to any Pool.
+- Implement Maximum Job Spool Size
+
+Maybe in 1.37:
- By the way: on page http://www.bacula.org/?page=tapedrives , at the
bottom, the link to "Tape Testing Chapter" is broken. It goes to
/html-manual/... while the others point to /rel-manual/...
a small reference.
- Linux Sony LIB-D81, AIT-3 library works.
- Device resource needs the "name" of the SD.
-- Add and option to see if the file size changed
- during backup.
-- Implement "update device" from SD so that DIR will
- always have current version of device.
-- Add disk seeking on restore.
-- Add Python writable variable for changing the Priority,
- Client, Storage, JobStatus (error), ...
-- SD Python
- - Solicit Events
-- FD Python
- - Python script to save with Python, not save, save with Bacula.
- - Python script to do backup.
+- Add and option to see if the file size changed during backup.
- Windows restore:
data-fd: RestoreFiles.2004-12-07_15.56.42 Error:
> ..\findlib\../../findlib/create_file.c:275 Could not open e:/: ERR=Der
and fix SD messages.
- Make sure SD deletes spool files on error exit.
- Delete old spool files when SD starts.
-- When Python creates a new label, the tape is immediately
- recycled and no label created. This happens when using
- autolabeling -- even when Python doesn't generate the name.
- Add a restore directory-x
- When labeling tapes, if you enter 000026, Bacula uses
the tape index rather than the Volume name 000026.
- Max Vols limit in Pool off by one?
-- Look at Preben's acl.c error handling code.
-- See multiple-store.txt for Multiple Storage implementation
- design.
-- Create a new GUI chapter explaining all the GUI programs.
- Tell the "restore" user when browsing is no longer possible.
- Require restore via the restore command or make a restore Job
get the bootstrap file.
- Add offline tape command to Bacula console.
- Document that Bootstrap files can be written with cataloging
turned off.
-- Look at adding full Volume and Pool information to a Volume
- label so that bscan can get *all* the info.
-- Scratch Pool where the volumes can be re-assigned to any Pool.
- Upgrade to MySQL 4.1.1 See:
http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
- Add client version to the Client name line that prints in
list, also it is maybe a good idea to check for the return value and
execute different actions based on the return value
-2. Priorities also for the Schedule Resource
-
- Why:
-
- With this it is possible to run monthly jobs at the end of the month
- instead of the beginning of the next month, so one could define
- weekly and monthly pools to be run on Fridays and if there are
- 2 Jobs resulting on the same time, the one with the higher priority
- takes precedence. This is also helpfull to implement a daily
- rotation scheme with an additional 2 weeks changing weekly pool
-
-Example:
- Schedule {
- Name = "NightlyBackup"
- Run = Priority = 1,Pool=Weekly friday at 21:00
- Run = Priority = 2,Pool=Weekly monthly on friday at 21:00
- Run = Priority = 3,Pool=Weekly yearly on friday at 21:00
- }
3. offline capability to bconsole
==========
- Can one write tapes faster with 8192 byte block sizes?
- Specify a single directory to restore.
-- Implement Maximum Job Spool Size
- Document security problems with the same password for everyone in
rpm and Win32 releases.
- Browse generations of files.
- Bootstrap from JobMedia records.
- Implement WildFile and WildDir to solve problem of
saving only *.doc files.
+- Fix
+ Please use the "label" command to create a new Volume for:
+ Storage: DDS-4-changer
+ Media type:
+ Pool: Default
+ label
+ The defined Storage resources are:
+- Copy Changer Device and Changer Command from Autochanger
+ to Device resource in SD if none given in Device resource.
+- 1. Automatic use of more than one drive in an autochanger (done)
+- 2. Automatic selection of the correct drive for each Job (i.e.
+ selects a drive with an appropriate Volume for the Job) (done)
+- 6. Allow multiple simultaneous Jobs referencing the same pool write
+ to several tapes (some new directive(s) are are probably needed for
+ this) (done)
+- Locking (done)
+- Key on Storage rather than Pool (done)
+- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
+- Synchronize multiple drives so that not more
+ than one loads a tape and any time (done)
+- 4. Use Changer Device and Changer Command specified in the
+ Autochanger resource, if none is found in the Device resource.
+ You can continue to specify them in the Device resource if you want
+ or need them to be different for each device.
+- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
+ that can allow a Device be part of an Autochanger, and hence the changer
+ script protected, but if set to no, will prevent the Device from being
+ automatically selected from the changer. This allows the device to
+ be directly accessed through its Device name, but not through the
+ AutoChanger name.
+#6 Select one from among Multiple Storage Devices for Job
+#5 Events that call a Python program
+ (Implemented in Dir/SD)
+- Make sure the Device name is in the Query packet returned.
+
int num_writers;
int max_writers; /* = 1 for files */
int reserved; /* number of reserves */
+ int num_drives; /* for autochanger */
+ bool autochanger; /* set if device is autochanger */
bool open;
bool append; /* in append mode */
bool read;
bool labeled;
- bool autochanger;
bool offline;
bool autoselect;
uint32_t PoolId;
static char *find_msg_start(char *msg);
static char Job_status[] = "Status Job=%127s JobStatus=%d\n";
+static char Device_update[] = "DevUpd Job=%127s "
+ "device=%127s "
+ "append=%d read=%d num_writers=%d "
+ "open=%d labeled=%d offline=%d "
+ "reserved=%d max_writers=%d "
+ "autoselect=%d autochanger=%d "
+ "poolid=%lld "
+ "changer_name=%127s media_type=%127s volume_name=%127s\n";
static char OK_msg[] = "1000 OK\n";
* to the appropriate handler. If the message is
* in any other format, it will be returned.
*
- * E.g. any message beginning with a digit will be returned.
- * any message beginning with Jmsg will be processed.
+ * E.g. any message beginning with a digit will be passed
+ * through to the caller.
+ * All other messages are expected begin with some identifier
+ * -- for the moment only the first character is checked, but
+ * at a later time, the whole identifier (e.g. Jmsg, CatReq, ...)
+ * could be checked. This is followed by Job=Jobname <user-defined>
+ * info. The identifier is used to dispatch the message to the right
+ * place (Job message, catalog request, ...). The Job is used to lookup
+ * the JCR so that the action is performed on the correct jcr, and
+ * the rest of the message is up to the user. Note, DevUpd uses
+ * *System* for the Job name, and hence no JCR is obtained. This
+ * is a *rare* case where a jcr is not really needed.
*
*/
int bget_dirmsg(BSOCK *bs)
Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
continue;
}
- if (!(jcr=get_jcr_by_full_name(Job))) {
+ if (strcmp(Job, "*System*") == 0) {
+ jcr = NULL; /* No jcr */
+ } else if (!(jcr=get_jcr_by_full_name(Job))) {
Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg);
continue;
}
char Job[MAX_NAME_LENGTH];
if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
jcr->SDJobStatus = JobStatus; /* current status */
- free_jcr(jcr);
- continue;
+ } else {
+ Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
}
+ free_jcr(jcr);
+ continue;
+ }
+ /* No JCR for Device Updates! */
+ if (bs->msg[0] = 'D') { /* Device update */
+ DEVICE *dev;
+ POOL_MEM dev_name, changer_name, media_type, volume_name;
+ int dev_open, dev_append, dev_read, dev_labeled;
+ int dev_offline, dev_autochanger, dev_autoselect;
+ int dev_num_writers, dev_max_writers, dev_reserved;
+ uint64_t dev_PoolId;
+ Dmsg1(100, "<stored: %s", bs->msg);
+ if (sscanf(bs->msg, Device_update,
+ &Job, dev_name.c_str(),
+ &dev_append, &dev_read,
+ &dev_num_writers, &dev_open,
+ &dev_labeled, &dev_offline, &dev_reserved,
+ &dev_max_writers, &dev_autoselect,
+ &dev_autochanger, &dev_PoolId,
+ changer_name.c_str(), media_type.c_str(),
+ volume_name.c_str()) != 16) {
+ Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
+ } else {
+ unbash_spaces(dev_name);
+ dev = (DEVICE *)GetResWithName(R_DEVICE, dev_name.c_str());
+ if (!dev) {
+ continue;
+ }
+ unbash_spaces(changer_name);
+ unbash_spaces(media_type);
+ unbash_spaces(volume_name);
+ bstrncpy(dev->ChangerName, changer_name.c_str(), sizeof(dev->ChangerName));
+ bstrncpy(dev->MediaType, media_type.c_str(), sizeof(dev->MediaType));
+ bstrncpy(dev->VolumeName, volume_name.c_str(), sizeof(dev->VolumeName));
+ /* Note, these are copied because they are boolean rather than
+ * integer.
+ */
+ dev->open = dev_open;
+ dev->append = dev_append;
+ dev->read = dev_read;
+ dev->labeled = dev_labeled;
+ dev->offline = dev_offline;
+ dev->autoselect = dev_autoselect;
+ dev->autochanger = dev_autochanger > 0;
+ dev->num_drives = dev_autochanger; /* does double duty */
+ dev->PoolId = dev_PoolId;
+ dev->num_writers = dev_num_writers;
+ dev->max_writers = dev_max_writers;
+ dev->reserved = dev_reserved;
+ dev->found = true;
+ }
+ continue;
}
return n;
}
/* Response from Storage daemon */
static char OKjob[] = "3000 OK Job SDid=%d SDtime=%d Authorization=%100s\n";
static char OK_device[] = "3000 OK use device device=%s\n";
-static char OK_query[] = "3001 OK query "
- "append=%d read=%d num_writers=%d "
- "open=%d labeled=%d offline=%d "
- "reserved=%d max_writers=%d "
- "autoselect=%d autochanger=%d "
- "poolid=%lld "
- "changer_name=%127s media_type=%127s volume_name=%127s";
/* Storage Daemon requests */
static char Job_start[] = "3010 Job %127s start\n";
*/
bool update_device_res(JCR *jcr, DEVICE *dev)
{
- POOL_MEM device_name, changer_name, media_type, volume_name;
- int dev_open, dev_append, dev_read, dev_labeled;
- int dev_offline, dev_autochanger, dev_autoselect;
+ POOL_MEM device_name;
BSOCK *sd;
if (!connect_to_storage_daemon(jcr, 5, 30, 0)) {
return false;
bash_spaces(device_name);
bnet_fsend(sd, query_device, device_name.c_str());
Dmsg1(100, ">stored: %s\n", sd->msg);
- if (bget_dirmsg(sd) > 0) {
- Dmsg1(100, "<stored: %s", sd->msg);
- if (sscanf(sd->msg, OK_query,
- &dev_append, &dev_read,
- &dev->num_writers, &dev_open,
- &dev_labeled, &dev_offline, &dev->reserved,
- &dev->max_writers, &dev_autoselect,
- &dev_autochanger, &dev->PoolId,
- changer_name.c_str(), media_type.c_str(),
- volume_name.c_str()) != 14) {
- return false;
- }
- unbash_spaces(changer_name);
- unbash_spaces(media_type);
- unbash_spaces(volume_name);
- bstrncpy(dev->ChangerName, changer_name.c_str(), sizeof(dev->ChangerName));
- bstrncpy(dev->MediaType, media_type.c_str(), sizeof(dev->MediaType));
- bstrncpy(dev->VolumeName, volume_name.c_str(), sizeof(dev->VolumeName));
- /* Note, these are copied because they are boolean rather than
- * integer.
- */
- dev->open = dev_open;
- dev->append = dev_append;
- dev->read = dev_read;
- dev->labeled = dev_labeled;
- dev->offline = dev_offline;
- dev->autoselect = dev_autoselect;
- dev->autochanger = dev_autochanger;
- dev->found = true;
- } else {
+ /* The data is returned through Device_update */
+ if (bget_dirmsg(sd) <= 0) {
return false;
}
return true;
jcr->errmsg = get_pool_memory(PM_MESSAGE);
jcr->errmsg[0] = 0;
/* Setup some dummy values */
- jcr->Job[0] = 0; /* no job name by default */
+ bstrncpy(jcr->Job, "*System*", sizeof(jcr->Job));
jcr->JobId = 0;
jcr->JobType = JT_SYSTEM; /* internal job until defined */
jcr->JobLevel = L_NONE;
" StartBlock=%u EndBlock=%u\n";
static char FileAttributes[] = "UpdCat Job=%s FileAttributes ";
static char Job_status[] = "Status Job=%s JobStatus=%d\n";
+static char Device_update[] = "DevUpd Job=%s device=%s "
+ "append=%d read=%d num_writers=%d "
+ "open=%d labeled=%d offline=%d "
+ "reserved=%d max_writers=%d "
+ "autoselect=%d autochanger=%d "
+ "poolid=%s "
+ "changer_name=%s media_type=%s volume_name=%s\n";
+
/* Responses received from the Director */
/* Forward referenced functions */
static int wait_for_sysop(DCR *dcr);
+/* Send update information about a device to Director */
+bool dir_update_device(JCR *jcr, DEVICE *dev)
+{
+ BSOCK *dir = jcr->dir_bsock;
+ POOL_MEM dev_name, VolumeName, MediaType, ChangerName;
+ DEVRES *device = dev->device;
+ bool ok;
+ char ed1[50];
+
+ pm_strcpy(dev_name, device->hdr.name);
+ bash_spaces(dev_name);
+ if (dev->is_labeled()) {
+ pm_strcpy(VolumeName, dev->VolHdr.VolName);
+ } else {
+ pm_strcpy(VolumeName, "*");
+ }
+ bash_spaces(VolumeName);
+ pm_strcpy(MediaType, device->media_type);
+ bash_spaces(MediaType);
+ if (device->changer_res) {
+ pm_strcpy(ChangerName, device->changer_res->hdr.name);
+ bash_spaces(ChangerName);
+ } else {
+ pm_strcpy(ChangerName, "*");
+ }
+ ok =bnet_fsend(dir, Device_update,
+ jcr->Job,
+ dev_name.c_str(),
+ dev->can_append()!=0,
+ dev->can_read()!=0, dev->num_writers,
+ dev->is_open()!=0, dev->is_labeled()!=0,
+ dev->is_offline()!=0, dev->reserved_device,
+ dev->is_tape()?100000:1,
+ dev->autoselect, 0,
+ edit_uint64(dev->PoolId, ed1),
+ ChangerName.c_str(), MediaType.c_str(), VolumeName.c_str());
+ Dmsg1(100, ">dird: %s\n", dir->msg);
+ return ok;
+}
+
+bool dir_update_changer(JCR *jcr, AUTOCHANGER *changer)
+{
+ BSOCK *dir = jcr->dir_bsock;
+ POOL_MEM dev_name, MediaType;
+ DEVRES *device;
+ bool ok;
+
+ pm_strcpy(dev_name, changer->hdr.name);
+ bash_spaces(dev_name);
+ device = (DEVRES *)changer->device->first();
+ pm_strcpy(MediaType, device->media_type);
+ bash_spaces(MediaType);
+ /* This is mostly to indicate that we are here */
+ ok = bnet_fsend(dir, Device_update,
+ jcr->Job,
+ dev_name.c_str(), /* Changer name */
+ 0, 0, 0, /* append, read, num_writers */
+ 0, 0, 0, /* is_open, is_labeled, offline */
+ 0, 0, /* reserved, max_writers */
+ 0, /* Autoselect */
+ changer->device->size(), /* Number of devices */
+ "0", /* PoolId */
+ "*", /* ChangerName */
+ MediaType.c_str(), /* MediaType */
+ "*"); /* VolName */
+ Dmsg1(100, ">dird: %s\n", dir->msg);
+ return ok;
+}
+
+
/*
* Send current JobStatus to Director
*/
static char NOT_open[] = "3925 Device \"%s\" could not be opened or does not exist.\n";
static char BAD_use[] = "3913 Bad use command: %s\n";
static char BAD_job[] = "3915 Bad Job command: %s\n";
-static char OK_query[] = "3001 OK query "
- "append=%d read=%d num_writers=%d "
- "open=%d labeled=%d offline=%d "
- "reserved=%d max_writers=%d "
- "autoselect=%d autochanger=%d "
- "poolid=%s "
- "changer_name=%s media_type=%s volume_name=%s";
-static char BAD_query[] = "3917 Bad query command: %s\n";
+static char OK_query[] = "3001 OK query\n";
+static char NO_query[] = "3918 Query failed\n";
+static char BAD_query[] = "3917 Bad query command: %s\n";
/*
* Director requests us to start a job
*/
bool query_cmd(JCR *jcr)
{
- POOL_MEM dev_name;
+ POOL_MEM dev_name, VolumeName, MediaType, ChangerName;
BSOCK *dir = jcr->dir_bsock;
DEVRES *device;
AUTOCHANGER *changer;
bool ok;
- char ed1[50];
Dmsg1(100, "Query_cmd: %s", dir->msg);
ok = sscanf(dir->msg, query_device, dev_name.c_str()) == 1;
if (!device->dev) {
break;
}
- DEVICE *dev = device->dev;
- POOL_MEM VolumeName, MediaType, ChangerName;
UnlockRes();
- if (dev->is_labeled()) {
- pm_strcpy(VolumeName, dev->VolHdr.VolName);
+ ok = dir_update_device(jcr, device->dev);
+ if (ok) {
+ ok = bnet_fsend(dir, OK_query);
} else {
- pm_strcpy(VolumeName, "*");
+ bnet_fsend(dir, NO_query);
}
- bash_spaces(VolumeName);
- pm_strcpy(MediaType, device->media_type);
- bash_spaces(MediaType);
- if (device->changer_res) {
- pm_strcpy(ChangerName, device->changer_res->hdr.name);
- bash_spaces(ChangerName);
- } else {
- pm_strcpy(ChangerName, "*");
- }
- ok =bnet_fsend(dir, OK_query,
- dev->can_append()!=0,
- dev->can_read()!=0, dev->num_writers,
- dev->is_open()!=0, dev->is_labeled()!=0,
- dev->is_offline()!=0, dev->reserved_device,
- dev->is_tape()?100000:1,
- dev->autoselect, 0,
- edit_uint64(dev->PoolId, ed1),
- ChangerName.c_str(), MediaType.c_str(), VolumeName.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
return ok;
}
}
/* Find resource, and make sure we were able to open it */
if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) {
UnlockRes();
- /* This is mostly to indicate that we are here */
- ok = bnet_fsend(dir, OK_query,
- 0, 0, 0, /* append, read, num_writers */
- 0, 0, 0, /* is_open, is_labeled, offline */
- 0, 0, /* reserved, max_writers */
- 0, 1, /* autoselect, AutoChanger = 1 */
- "0", /* PoolId */
- "*", "*", "*"); /* ChangerName, MediaType, VolName */
- Dmsg1(100, ">dird: %s\n", dir->msg);
+ if (!changer->device || changer->device->size() == 0) {
+ continue; /* no devices */
+ }
+ ok = dir_update_changer(jcr, changer);
+ if (ok) {
+ ok = bnet_fsend(dir, OK_query);
+ } else {
+ bnet_fsend(dir, NO_query);
+ }
return ok;
}
}
uint32_t new_VolSessionId();
/* From acquire.c */
-bool reserve_device_for_append(JCR *jcr, DEVICE *dev);
-DCR *acquire_device_for_append(JCR *jcr, DEVICE *dev);
-bool reserve_device_for_read(JCR *jcr, DEVICE *dev);
-DCR *acquire_device_for_read(JCR *jcr, DEVICE *dev);
-bool release_device(DCR *dcr);
-DCR *new_dcr(JCR *jcr, DEVICE *dev);
-void free_dcr(DCR *dcr);
+bool reserve_device_for_append(JCR *jcr, DEVICE *dev);
+DCR *acquire_device_for_append(JCR *jcr, DEVICE *dev);
+bool reserve_device_for_read(JCR *jcr, DEVICE *dev);
+DCR *acquire_device_for_read(JCR *jcr, DEVICE *dev);
+bool release_device(DCR *dcr);
+DCR *new_dcr(JCR *jcr, DEVICE *dev);
+void free_dcr(DCR *dcr);
/* From askdir.c */
enum get_vol_info_rw {
GET_VOL_INFO_FOR_WRITE,
GET_VOL_INFO_FOR_READ
};
-bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
-bool dir_find_next_appendable_volume(DCR *dcr);
-bool dir_update_volume_info(DCR *dcr, bool label);
-bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
-bool dir_ask_sysop_to_mount_volume(DCR *dcr);
-bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
-bool dir_send_job_status(JCR *jcr);
-bool dir_create_jobmedia_record(DCR *dcr);
+bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
+bool dir_find_next_appendable_volume(DCR *dcr);
+bool dir_update_volume_info(DCR *dcr, bool label);
+bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
+bool dir_ask_sysop_to_mount_volume(DCR *dcr);
+bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
+bool dir_send_job_status(JCR *jcr);
+bool dir_create_jobmedia_record(DCR *dcr);
+bool dir_update_device(JCR *jcr, DEVICE *dev);
+bool dir_update_changer(JCR *jcr, AUTOCHANGER *changer);
/* authenticate.c */
-int authenticate_director(JCR *jcr);
-int authenticate_filed(JCR *jcr);
+int authenticate_director(JCR *jcr);
+int authenticate_filed(JCR *jcr);
/* From autochanger.c */
-int autoload_device(DCR *dcr, int writing, BSOCK *dir);
-bool autochanger_list(DCR *dcr, BSOCK *dir);
-void mark_volume_not_inchanger(DCR *dcr);
-char *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
+int autoload_device(DCR *dcr, int writing, BSOCK *dir);
+bool autochanger_list(DCR *dcr, BSOCK *dir);
+void mark_volume_not_inchanger(DCR *dcr);
+char *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
/* From block.c */
-void dump_block(DEV_BLOCK *b, const char *msg);
+void dump_block(DEV_BLOCK *b, const char *msg);
DEV_BLOCK *new_block(DEVICE *dev);
DEV_BLOCK *dup_block(DEV_BLOCK *eblock);
-void init_block_write(DEV_BLOCK *block);
-void empty_block(DEV_BLOCK *block);
-void free_block(DEV_BLOCK *block);
-bool write_block_to_device(DCR *dcr);
-bool write_block_to_dev(DCR *dcr);
-void print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
-void ser_block_header(DEV_BLOCK *block);
+void init_block_write(DEV_BLOCK *block);
+void empty_block(DEV_BLOCK *block);
+void free_block(DEV_BLOCK *block);
+bool write_block_to_device(DCR *dcr);
+bool write_block_to_dev(DCR *dcr);
+void print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
+void ser_block_header(DEV_BLOCK *block);
#define CHECK_BLOCK_NUMBERS true
#define NO_BLOCK_NUMBER_CHECK false
-bool read_block_from_device(DCR *dcr, bool check_block_numbers);
-bool read_block_from_dev(DCR *dcr, bool check_block_numbers);
+bool read_block_from_device(DCR *dcr, bool check_block_numbers);
+bool read_block_from_dev(DCR *dcr, bool check_block_numbers);
/* From butil.c -- utilities for SD tool programs */
-void print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
+void print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr,
- const char *VolumeName, int mode);
-void display_tape_error_status(JCR *jcr, DEVICE *dev);
+ const char *VolumeName, int mode);
+void display_tape_error_status(JCR *jcr, DEVICE *dev);
/* From dev.c */
-DEVICE *init_dev(JCR *jcr, DEVICE *dev, DEVRES *device);
-int open_dev(DEVICE *dev, char *VolName, int mode);
-off_t lseek_dev(DEVICE *dev, off_t offset, int whence);
-int open_first_part(DEVICE *dev);
-int open_next_part(DEVICE *dev);
-int open_guess_name_dev(DEVICE *dev);
-void close_dev(DEVICE *dev);
-void force_close_dev(DEVICE *dev);
-bool truncate_dev(DEVICE *dev);
-void term_dev(DEVICE *dev);
-char * strerror_dev(DEVICE *dev);
-void clrerror_dev(DEVICE *dev, int func);
-bool update_pos_dev(DEVICE *dev);
-bool rewind_dev(DEVICE *dev);
-bool load_dev(DEVICE *dev);
-bool offline_dev(DEVICE *dev);
-int flush_dev(DEVICE *dev);
-int weof_dev(DEVICE *dev, int num);
-int write_block(DEVICE *dev);
+DEVICE *init_dev(JCR *jcr, DEVICE *dev, DEVRES *device);
+int open_dev(DEVICE *dev, char *VolName, int mode);
+off_t lseek_dev(DEVICE *dev, off_t offset, int whence);
+int open_first_part(DEVICE *dev);
+int open_next_part(DEVICE *dev);
+int open_guess_name_dev(DEVICE *dev);
+void close_dev(DEVICE *dev);
+void force_close_dev(DEVICE *dev);
+bool truncate_dev(DEVICE *dev);
+void term_dev(DEVICE *dev);
+char * strerror_dev(DEVICE *dev);
+void clrerror_dev(DEVICE *dev, int func);
+bool update_pos_dev(DEVICE *dev);
+bool rewind_dev(DEVICE *dev);
+bool load_dev(DEVICE *dev);
+bool offline_dev(DEVICE *dev);
+int flush_dev(DEVICE *dev);
+int weof_dev(DEVICE *dev, int num);
+int write_block(DEVICE *dev);
uint32_t status_dev(DEVICE *dev);
-int eod_dev(DEVICE *dev);
-bool fsf_dev(DEVICE *dev, int num);
-bool fsr_dev(DEVICE *dev, int num);
-bool bsf_dev(DEVICE *dev, int num);
-bool bsr_dev(DEVICE *dev, int num);
-void attach_jcr_to_device(DEVICE *dev, JCR *jcr);
-void detach_jcr_from_device(DEVICE *dev, JCR *jcr);
-JCR *next_attached_jcr(DEVICE *dev, JCR *jcr);
-bool dev_can_write(DEVICE *dev);
-bool offline_or_rewind_dev(DEVICE *dev);
-bool reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
-void init_dev_wait_timers(DEVICE *dev);
-bool double_dev_wait_time(DEVICE *dev);
+int eod_dev(DEVICE *dev);
+bool fsf_dev(DEVICE *dev, int num);
+bool fsr_dev(DEVICE *dev, int num);
+bool bsf_dev(DEVICE *dev, int num);
+bool bsr_dev(DEVICE *dev, int num);
+void attach_jcr_to_device(DEVICE *dev, JCR *jcr);
+void detach_jcr_from_device(DEVICE *dev, JCR *jcr);
+JCR *next_attached_jcr(DEVICE *dev, JCR *jcr);
+bool dev_can_write(DEVICE *dev);
+bool offline_or_rewind_dev(DEVICE *dev);
+bool reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
+void init_dev_wait_timers(DEVICE *dev);
+bool double_dev_wait_time(DEVICE *dev);
/* Get info about device */
-char * dev_name(DEVICE *dev);
-char * dev_vol_name(DEVICE *dev);
+char * dev_name(DEVICE *dev);
+char * dev_vol_name(DEVICE *dev);
uint32_t dev_block(DEVICE *dev);
uint32_t dev_file(DEVICE *dev);
-bool dev_is_tape(DEVICE *dev);
+bool dev_is_tape(DEVICE *dev);
/* From device.c */
-bool open_device(DCR *dcr);
-bool first_open_device(DEVICE *dev);
-bool fixup_device_block_write_error(DCR *dcr);
-void _lock_device(const char *file, int line, DEVICE *dev);
-void _unlock_device(const char *file, int line, DEVICE *dev);
-void _block_device(const char *file, int line, DEVICE *dev, int state);
-void _unblock_device(const char *file, int line, DEVICE *dev);
-void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
-void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
-void set_new_volume_parameters(DCR *dcr);
-void set_new_file_parameters(DCR *dcr);
-bool device_is_unmounted(DEVICE *dev);
-void dev_lock(DEVICE *dev);
-void dev_unlock(DEVICE *dev);
+bool open_device(DCR *dcr);
+bool first_open_device(DEVICE *dev);
+bool fixup_device_block_write_error(DCR *dcr);
+void _lock_device(const char *file, int line, DEVICE *dev);
+void _unlock_device(const char *file, int line, DEVICE *dev);
+void _block_device(const char *file, int line, DEVICE *dev, int state);
+void _unblock_device(const char *file, int line, DEVICE *dev);
+void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
+void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
+void set_new_volume_parameters(DCR *dcr);
+void set_new_file_parameters(DCR *dcr);
+bool device_is_unmounted(DEVICE *dev);
+void dev_lock(DEVICE *dev);
+void dev_unlock(DEVICE *dev);
const char *edit_blocked_reason(DEVICE *dev);
/* From dircmd.c */
-void *handle_connection_request(void *arg);
+void *handle_connection_request(void *arg);
/* From fd_cmds.c */
-void run_job(JCR *jcr);
-bool bootstrap_cmd(JCR *jcr);
+void run_job(JCR *jcr);
+bool bootstrap_cmd(JCR *jcr);
/* From job.c */
-void stored_free_jcr(JCR *jcr);
-void connection_from_filed(void *arg);
-void handle_filed_connection(BSOCK *fd, char *job_name);
+void stored_free_jcr(JCR *jcr);
+void connection_from_filed(void *arg);
+void handle_filed_connection(BSOCK *fd, char *job_name);
/* From label.c */
-int read_dev_volume_label(DCR *dcr);
-int read_dev_volume_label_guess(DCR *dcr, bool write);
-void create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
-void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
-bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
-bool write_ansi_ibm_label(DCR *dcr, const char *VolName);
-int read_ansi_ibm_label(DCR *dcr);
-bool write_session_label(DCR *dcr, int label);
-bool write_volume_label_to_block(DCR *dcr);
-bool rewrite_volume_label(DCR *dcr, bool recycle);
-void dump_volume_label(DEVICE *dev);
-void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+int read_dev_volume_label(DCR *dcr);
+int read_dev_volume_label_guess(DCR *dcr, bool write);
+void create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
+void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
+bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
+bool write_ansi_ibm_label(DCR *dcr, const char *VolName);
+int read_ansi_ibm_label(DCR *dcr);
+bool write_session_label(DCR *dcr, int label);
+bool write_volume_label_to_block(DCR *dcr);
+bool rewrite_volume_label(DCR *dcr, bool recycle);
+void dump_volume_label(DEVICE *dev);
+void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
/* From match_bsr.c */
-int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
- SESSION_LABEL *sesrec);
-int match_bsr_block(BSR *bsr, DEV_BLOCK *block);
-void position_bsr_block(BSR *bsr, DEV_BLOCK *block);
-BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev);
-bool match_set_eof(BSR *bsr, DEV_RECORD *rec);
+int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
+ SESSION_LABEL *sesrec);
+int match_bsr_block(BSR *bsr, DEV_BLOCK *block);
+void position_bsr_block(BSR *bsr, DEV_BLOCK *block);
+BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev);
+bool match_set_eof(BSR *bsr, DEV_RECORD *rec);
/* From mount.c */
-bool mount_next_write_volume(DCR *dcr, bool release);
-bool mount_next_read_volume(DCR *dcr);
-void release_volume(DCR *ddr);
-void mark_volume_in_error(DCR *dcr);
+bool mount_next_write_volume(DCR *dcr, bool release);
+bool mount_next_read_volume(DCR *dcr);
+void release_volume(DCR *ddr);
+void mark_volume_in_error(DCR *dcr);
/* From parse_bsr.c */
-BSR *parse_bsr(JCR *jcr, char *lf);
-void dump_bsr(BSR *bsr, bool recurse);
-void free_bsr(BSR *bsr);
+BSR *parse_bsr(JCR *jcr, char *lf);
+void dump_bsr(BSR *bsr, bool recurse);
+void free_bsr(BSR *bsr);
VOL_LIST *new_vol();
-int add_vol(JCR *jcr, VOL_LIST *vol);
-void free_vol_list(JCR *jcr);
-void create_vol_list(JCR *jcr);
+int add_vol(JCR *jcr, VOL_LIST *vol);
+void free_vol_list(JCR *jcr);
+void create_vol_list(JCR *jcr);
/* From record.c */
const char *FI_to_ascii(int fi);
const char *stream_to_ascii(int stream, int fi);
-bool write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
DEV_RECORD *new_record();
-void free_record(DEV_RECORD *rec);
-void empty_record(DEV_RECORD *rec);
+void free_record(DEV_RECORD *rec);
+void empty_record(DEV_RECORD *rec);
/* From read_record.c */
bool read_records(DCR *dcr,
bool mount_cb(DCR *dcr));
/* From spool.c */
-bool begin_data_spool (DCR *dcr);
-bool discard_data_spool (DCR *dcr);
-bool commit_data_spool (DCR *dcr);
-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);
-void list_spool_stats (BSOCK *bs);
+bool begin_data_spool (DCR *dcr);
+bool discard_data_spool (DCR *dcr);
+bool commit_data_spool (DCR *dcr);
+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);
+void list_spool_stats (BSOCK *bs);
/* Check Configuration file for necessary info */
static void check_config()
{
+ AUTOCHANGER *changer;
+
LockRes();
me = (STORES *)GetNextRes(R_STORAGE, NULL);
if (!me) {
Jmsg1(NULL, M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
configfile);
}
-
my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */
if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
close_msg(NULL); /* close temp message handler */
init_msg(NULL, me->messages); /* open daemon message handler */
- UnlockRes();
if (!me->working_directory) {
Jmsg1(NULL, M_ERROR_TERM, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
configfile);
}
-
set_working_directory(me->working_directory);
+
+ /* Ensure that the media_type for each device is the same */
+ foreach_res(changer, R_AUTOCHANGER) {
+ DEVRES *device;
+ char *media_type = NULL;
+ foreach_alist(device, changer->device) {
+ if (media_type == NULL) {
+ media_type = device->media_type;
+ continue;
+ }
+ if (strcmp(media_type, device->media_type) != 0) {
+ Jmsg(NULL, M_ERROR_TERM, 0,
+ _("Media Type not the same for all devices in changer %s. Cannot continue.\n"),
+ changer->hdr.name);
+ }
+ /*
+ * If the device does not have a changer name or changer command
+ * defined, used the one from the Autochanger resource
+ */
+ if (!device->changer_name) {
+ device->changer_name = bstrdup(changer->changer_name);
+ }
+ if (!device->changer_command) {
+ device->changer_command = bstrdup(changer->changer_command);
+ }
+ }
+ }
+ UnlockRes();
}
/*
{"name", store_name, ITEM(res_changer.hdr.name), 0, ITEM_REQUIRED, 0},
{"description", store_str, ITEM(res_changer.hdr.desc), 0, 0, 0},
{"device", store_alist_res, ITEM(res_changer.device), R_DEVICE, ITEM_REQUIRED, 0},
- {"changerdevice", store_strname, ITEM(res_changer.changer_name), 0, 0, 0},
- {"changercommand", store_strname, ITEM(res_changer.changer_command), 0, 0, 0},
+ {"changerdevice", store_strname, ITEM(res_changer.changer_name), 0, ITEM_REQUIRED, 0},
+ {"changercommand", store_strname, ITEM(res_changer.changer_command), 0, ITEM_REQUIRED, 0},
{NULL, NULL, 0, 0, 0, 0}
};
{"device", dev_items, R_DEVICE},
{"messages", msgs_items, R_MSGS},
{"autochanger", changer_items, R_AUTOCHANGER},
- {NULL, NULL, 0}
+ {NULL, NULL, 0}
};
return;
}
sendit(sock, "dump_resource type=%d\n", type);
- if (type < 0) { /* no recursion */
+ if (type < 0) { /* no recursion */
type = - type;
recurse = 0;
}
break;
case R_STORAGE:
sendit(sock, "Storage: name=%s SDaddr=%s SDport=%d SDDport=%d HB=%s\n",
- res->res_store.hdr.name,
- NPRT(get_first_address(res->res_store.sdaddrs, buf, sizeof(buf))),
- get_first_port_host_order(res->res_store.sdaddrs),
- get_first_port_host_order(res->res_store.sddaddrs),
- edit_utime(res->res_store.heartbeat_interval, buf, sizeof(buf)));
+ res->res_store.hdr.name,
+ NPRT(get_first_address(res->res_store.sdaddrs, buf, sizeof(buf))),
+ get_first_port_host_order(res->res_store.sdaddrs),
+ get_first_port_host_order(res->res_store.sddaddrs),
+ edit_utime(res->res_store.heartbeat_interval, buf, sizeof(buf)));
if (res->res_store.sdaddrs) {
- foreach_dlist(p, res->res_store.sdaddrs) {
+ foreach_dlist(p, res->res_store.sdaddrs) {
sendit(sock, " SDaddr=%s SDport=%d\n",
- p->get_address(buf, sizeof(buf)), p->get_port_host_order());
- }
+ p->get_address(buf, sizeof(buf)), p->get_port_host_order());
+ }
}
if (res->res_store.sddaddrs) {
- foreach_dlist(p, res->res_store.sddaddrs) {
+ foreach_dlist(p, res->res_store.sddaddrs) {
sendit(sock, " SDDaddr=%s SDDport=%d\n",
- p->get_address(buf, sizeof(buf)), p->get_port_host_order());
- }
+ p->get_address(buf, sizeof(buf)), p->get_port_host_order());
+ }
}
break;
case R_DEVICE:
sendit(sock, "Device: name=%s MediaType=%s Device=%s LabelType=%d\n",
- res->res_dev.hdr.name,
- res->res_dev.media_type, res->res_dev.device_name,
- res->res_dev.label_type);
+ res->res_dev.hdr.name,
+ res->res_dev.media_type, res->res_dev.device_name,
+ res->res_dev.label_type);
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", NPRT(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);
+ res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
if (res->res_dev.changer_res) {
sendit(sock, " changer=%p\n", res->res_dev.changer_res);
}
case R_AUTOCHANGER:
DEVRES *dev;
sendit(sock, "Changer: name=%s Changer_devname=%s\n Changer_cmd=%s\n",
- res->res_changer.hdr.name,
- res->res_changer.changer_name, res->res_changer.changer_command);
+ res->res_changer.hdr.name,
+ res->res_changer.changer_name, res->res_changer.changer_command);
foreach_alist(dev, res->res_changer.device) {
sendit(sock, " --->Device: name=%s\n", dev->hdr.name);
}
switch (type) {
case R_DIRECTOR:
if (res->res_dir.password) {
- free(res->res_dir.password);
+ free(res->res_dir.password);
}
if (res->res_dir.address) {
- free(res->res_dir.address);
+ free(res->res_dir.address);
}
break;
case R_AUTOCHANGER:
if (res->res_changer.changer_name) {
- free(res->res_changer.changer_name);
+ free(res->res_changer.changer_name);
}
if (res->res_changer.changer_command) {
- free(res->res_changer.changer_command);
+ free(res->res_changer.changer_command);
}
if (res->res_changer.device) {
- delete res->res_changer.device;
+ delete res->res_changer.device;
}
break;
case R_STORAGE:
if (res->res_store.sdaddrs) {
- free_addresses(res->res_store.sdaddrs);
+ free_addresses(res->res_store.sdaddrs);
}
if (res->res_store.sddaddrs) {
- free_addresses(res->res_store.sddaddrs);
+ free_addresses(res->res_store.sddaddrs);
}
if (res->res_store.working_directory) {
- free(res->res_store.working_directory);
+ free(res->res_store.working_directory);
}
if (res->res_store.pid_directory) {
- free(res->res_store.pid_directory);
+ free(res->res_store.pid_directory);
}
if (res->res_store.subsys_directory) {
- free(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);
+ free(res->res_dev.media_type);
}
if (res->res_dev.device_name) {
- free(res->res_dev.device_name);
+ free(res->res_dev.device_name);
}
if (res->res_dev.changer_name) {
- free(res->res_dev.changer_name);
+ free(res->res_dev.changer_name);
}
if (res->res_dev.changer_command) {
- free(res->res_dev.changer_command);
+ free(res->res_dev.changer_command);
}
if (res->res_dev.alert_command) {
- free(res->res_dev.alert_command);
+ free(res->res_dev.alert_command);
}
if (res->res_dev.spool_directory) {
- free(res->res_dev.spool_directory);
+ free(res->res_dev.spool_directory);
}
if (res->res_dev.mount_point) {
- free(res->res_dev.mount_point);
+ free(res->res_dev.mount_point);
}
if (res->res_dev.mount_command) {
- free(res->res_dev.mount_command);
+ free(res->res_dev.mount_command);
}
if (res->res_dev.unmount_command) {
- free(res->res_dev.unmount_command);
+ free(res->res_dev.unmount_command);
}
if (res->res_dev.write_part_command) {
- free(res->res_dev.write_part_command);
+ free(res->res_dev.write_part_command);
}
if (res->res_dev.free_space_command) {
- free(res->res_dev.free_space_command);
+ free(res->res_dev.free_space_command);
}
break;
case R_MSGS:
if (res->res_msgs.mail_cmd) {
- free(res->res_msgs.mail_cmd);
+ free(res->res_msgs.mail_cmd);
}
if (res->res_msgs.operator_cmd) {
- free(res->res_msgs.operator_cmd);
+ free(res->res_msgs.operator_cmd);
}
free_msgs_res((MSGS *)res); /* free message resource */
res = NULL;
*/
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_ERROR_TERM, 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) {
case R_DIRECTOR:
case R_DEVICE:
case R_MSGS:
- break;
+ break;
/* Resources containing a resource or an alist */
case R_STORAGE:
- if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
+ if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource \"%s\"\n", res_all.res_dir.hdr.name);
- }
- res->res_store.messages = res_all.res_store.messages;
- break;
+ }
+ res->res_store.messages = res_all.res_store.messages;
+ break;
case R_AUTOCHANGER:
- if ((res = (URES *)GetResWithName(type, res_all.res_changer.hdr.name)) == NULL) {
+ if ((res = (URES *)GetResWithName(type, res_all.res_changer.hdr.name)) == NULL) {
Emsg1(M_ERROR_TERM, 0, "Cannot find AutoChanger resource %s\n",
- res_all.res_changer.hdr.name);
- }
- /* we must explicitly copy the device alist pointer */
- res->res_changer.device = res_all.res_changer.device;
- /*
- * Now update each device in this resource to point back
- * to the changer resource.
- */
- foreach_alist(dev, res->res_changer.device) {
- dev->changer_res = (AUTOCHANGER *)&res->res_changer;
- }
- if ((errstat = pthread_mutex_init(&res->res_changer.changer_mutex, NULL)) != 0) {
- berrno be;
+ res_all.res_changer.hdr.name);
+ }
+ /* we must explicitly copy the device alist pointer */
+ res->res_changer.device = res_all.res_changer.device;
+ /*
+ * Now update each device in this resource to point back
+ * to the changer resource.
+ */
+ foreach_alist(dev, res->res_changer.device) {
+ dev->changer_res = (AUTOCHANGER *)&res->res_changer;
+ }
+ if ((errstat = pthread_mutex_init(&res->res_changer.changer_mutex, NULL)) != 0) {
+ berrno be;
Jmsg1(NULL, M_ERROR_TERM, 0, _("Unable to init mutex: ERR=%s\n"),
- be.strerror(errstat));
- }
- break;
+ be.strerror(errstat));
+ }
+ 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;
}
/* 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;
case R_AUTOCHANGER:
- size = sizeof(AUTOCHANGER);
- break;
+ size = sizeof(AUTOCHANGER);
+ 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 (!res_head[rindex]) {
- res_head[rindex] = (RES *)res; /* store first entry */
+ res_head[rindex] = (RES *)res; /* store first entry */
} else {
- RES *next;
- /* Add new res to end of chain */
- for (next=res_head[rindex]; 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=res_head[rindex]; 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);
}
}
}
R_MSGS,
R_AUTOCHANGER,
R_FIRST = R_DIRECTOR,
- R_LAST = R_AUTOCHANGER /* keep this updated */
+ R_LAST = R_AUTOCHANGER /* keep this updated */
};
enum {
/* Definition of the contents of each Resource */
class DIRRES {
public:
- RES hdr;
+ RES hdr;
- char *password; /* Director password */
- char *address; /* Director IP address or zero */
- int enable_ssl; /* Use SSL with this Director */
- int monitor; /* Have only access to status and .status functions */
+ char *password; /* Director password */
+ char *address; /* Director IP address or zero */
+ int enable_ssl; /* Use SSL with this Director */
+ int monitor; /* Have only access to status and .status functions */
};
/* Storage daemon "global" definitions */
class s_res_store {
public:
- RES hdr;
+ RES hdr;
dlist *sdaddrs;
dlist *sddaddrs;
- char *working_directory; /* working directory for checkpoints */
+ char *working_directory; /* working directory for checkpoints */
char *pid_directory;
char *subsys_directory;
- int require_ssl; /* Require SSL on all connections */
+ int require_ssl; /* Require SSL on all connections */
uint32_t max_concurrent_jobs; /* maximum concurrent jobs to run */
- MSGS *messages; /* Daemon message handler */
- utime_t heartbeat_interval; /* Interval to send hb to FD */
+ MSGS *messages; /* Daemon message handler */
+ utime_t heartbeat_interval; /* Interval to send hb to FD */
};
typedef struct s_res_store STORES;
public:
RES hdr;
alist *device;
- char *changer_name; /* Changer device name */
- char *changer_command; /* Changer command -- external program */
+ char *changer_name; /* Changer device name */
+ char *changer_command; /* Changer command -- external program */
pthread_mutex_t changer_mutex; /* One changer operation at a time */
};
/* Device specific definitions */
class DEVRES {
public:
- RES hdr;
-
- char *media_type; /* User assigned media type */
- char *device_name; /* Archive device name */
- char *changer_name; /* Changer device name */
- char *changer_command; /* Changer command -- external program */
- char *alert_command; /* Alert command -- external program */
- char *spool_directory; /* Spool file directory */
- int label_type; /* label type */
- int autoselect; /* Automatically select from AutoChanger */
- uint32_t drive_index; /* Autochanger drive index */
- 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 */
- uint32_t max_open_wait; /* maximum secs to wait for open */
- uint32_t max_open_vols; /* maximum simultaneous open volumes */
- 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 */
+ RES hdr;
+
+ char *media_type; /* User assigned media type */
+ char *device_name; /* Archive device name */
+ char *changer_name; /* Changer device name */
+ char *changer_command; /* Changer command -- external program */
+ char *alert_command; /* Alert command -- external program */
+ char *spool_directory; /* Spool file directory */
+ int label_type; /* label type */
+ int autoselect; /* Automatically select from AutoChanger */
+ uint32_t drive_index; /* Autochanger drive index */
+ 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 */
+ uint32_t max_open_wait; /* maximum secs to wait for open */
+ uint32_t max_open_vols; /* maximum simultaneous open volumes */
+ 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 */
uint32_t max_network_buffer_size; /* max network buf size */
- utime_t vol_poll_interval; /* interval between polling volume during mount */
- int64_t max_volume_files; /* max files to put on one volume */
- 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 */
+ utime_t vol_poll_interval; /* interval between polling volume during mount */
+ int64_t max_volume_files; /* max files to put on one volume */
+ 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 */
- int64_t max_part_size; /* Max part size */
- char *mount_point; /* Mount point for require mount devices */
- char *mount_command; /* Mount command */
- char *unmount_command; /* Unmount command */
- char *write_part_command; /* Write part command */
- char *free_space_command; /* Free space command */
+ int64_t max_part_size; /* Max part size */
+ char *mount_point; /* Mount point for require mount devices */
+ char *mount_command; /* Mount command */
+ char *unmount_command; /* Unmount command */
+ char *write_part_command; /* Write part command */
+ char *free_space_command; /* Free space command */
/* The following are set at runtime */
- DEVICE *dev; /* Pointer to phyical dev -- set at runtime */
- AUTOCHANGER *changer_res; /* pointer to changer res if any */
+ DEVICE *dev; /* Pointer to phyical dev -- set at runtime */
+ AUTOCHANGER *changer_res; /* pointer to changer res if any */
};
DEVRES res_dev;
MSGS res_msgs;
AUTOCHANGER res_changer;
- RES hdr;
+ RES hdr;
};
/* */
#undef VERSION
#define VERSION "1.37.6"
-#define BDATE "06 March 2005"
-#define LSMDATE "06Mar05"
+#define BDATE "07 March 2005"
+#define LSMDATE "07Mar05"
/* Debug flags */
#undef DEBUG