1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5    Copyright (C) 2011-2012 Planets Communications B.V.
6    Copyright (C) 2013-2021 Bareos GmbH & Co. KG
7 
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    Affero General Public License for more details.
17 
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22 */
23 
24 #include "lib/parse_conf.h"
25 #include "stored/autoxflate.h"
26 #include "stored/device_resource.h"
27 #include "stored/stored_globals.h"
28 
29 namespace storagedaemon {
30 
DeviceResource()31 DeviceResource::DeviceResource()
32     : BareosResource()
33     , media_type(nullptr)
34     , archive_device_string(nullptr)
35     , device_options(nullptr)
36     , diag_device_name(nullptr)
37     , changer_name(nullptr)
38     , changer_command(nullptr)
39     , alert_command(nullptr)
40     , spool_directory(nullptr)
41     , dev_type(DeviceType::B_UNKNOWN_DEV)
42     , label_type(B_BAREOS_LABEL)
43     , autoselect(true)
44     , norewindonclose(true)
45     , drive_tapealert_enabled(false)
46     , drive_crypto_enabled(false)
47     , query_crypto_status(false)
48     , collectstats(false)
49     , eof_on_error_is_eot(false)
50     , drive(0)
51     , drive_index(0)
52     , cap_bits{0}
53     , max_changer_wait(300)
54     , max_rewind_wait(300)
55     , max_open_wait(300)
56     , max_open_vols(1)
57     , label_block_size(64512)
58     , min_block_size(0)
59     , max_block_size(0)
60     , max_network_buffer_size(0)
61     , max_concurrent_jobs(0)
62     , autodeflate_algorithm(0)
63     , autodeflate_level(6)
64     , autodeflate(AutoXflateMode::IO_DIRECTION_NONE)
65     , autoinflate(AutoXflateMode::IO_DIRECTION_NONE)
66     , vol_poll_interval(300)
67     , max_volume_size(0)
68     , max_file_size(1000000000)
69     , volume_capacity(0)
70     , max_spool_size(0)
71     , max_job_spool_size(0)
72 
73     , max_part_size(0)
74     , mount_point(nullptr)
75     , mount_command(nullptr)
76     , unmount_command(nullptr)
77     , write_part_command(nullptr)
78     , free_space_command(nullptr)
79     , count(1)
80     , multiplied_device_resource(nullptr)
81 
82     , dev(nullptr)
83     , changer_res(nullptr)
84 
85     /* private: */
86     , temporarily_swapped_numbered_name(nullptr)
87 {
88   return;
89 }
90 
DeviceResource(const DeviceResource & other)91 DeviceResource::DeviceResource(const DeviceResource& other)
92     : BareosResource(other)
93     , media_type(nullptr)
94     , archive_device_string(nullptr)
95     , device_options(nullptr)
96     , diag_device_name(nullptr)
97     , changer_name(nullptr)
98     , changer_command(nullptr)
99     , alert_command(nullptr)
100     , spool_directory(nullptr)
101     , mount_point(nullptr)
102     , mount_command(nullptr)
103     , unmount_command(nullptr)
104     , write_part_command(nullptr)
105     , free_space_command(nullptr)
106     , temporarily_swapped_numbered_name(nullptr) /* should not copy */
107 {
108   if (other.media_type) { media_type = strdup(other.media_type); }
109   if (other.archive_device_string) {
110     archive_device_string = strdup(other.archive_device_string);
111   }
112   if (other.device_options) { device_options = strdup(other.device_options); }
113   if (other.diag_device_name) {
114     diag_device_name = strdup(other.diag_device_name);
115   }
116   if (other.changer_name) { changer_name = strdup(other.changer_name); }
117   if (other.changer_command) {
118     changer_command = strdup(other.changer_command);
119   }
120   if (other.alert_command) { alert_command = strdup(other.alert_command); }
121   if (other.spool_directory) {
122     spool_directory = strdup(other.spool_directory);
123   }
124   dev_type = other.dev_type;
125   label_type = other.label_type;
126   autoselect = other.autoselect;
127   norewindonclose = other.norewindonclose;
128   drive_tapealert_enabled = other.drive_tapealert_enabled;
129   drive_crypto_enabled = other.drive_crypto_enabled;
130   query_crypto_status = other.query_crypto_status;
131   collectstats = other.collectstats;
132   eof_on_error_is_eot = other.eof_on_error_is_eot;
133   drive = other.drive;
134   drive_index = other.drive_index;
135   memcpy(cap_bits, other.cap_bits, CAP_BYTES);
136   max_changer_wait = other.max_changer_wait;
137   max_rewind_wait = other.max_rewind_wait;
138   max_open_wait = other.max_open_wait;
139   max_open_vols = other.max_open_vols;
140   label_block_size = other.label_block_size;
141   min_block_size = other.min_block_size;
142   max_block_size = other.max_block_size;
143   max_network_buffer_size = other.max_network_buffer_size;
144   max_concurrent_jobs = other.max_concurrent_jobs;
145   autodeflate_algorithm = other.autodeflate_algorithm;
146   autodeflate_level = other.autodeflate_level;
147   autodeflate = other.autodeflate;
148   autoinflate = other.autoinflate;
149   vol_poll_interval = other.vol_poll_interval;
150   max_volume_size = other.max_volume_size;
151   max_file_size = other.max_file_size;
152   volume_capacity = other.volume_capacity;
153   max_spool_size = other.max_spool_size;
154   max_job_spool_size = other.max_job_spool_size;
155 
156   max_part_size = other.max_part_size;
157   if (other.mount_point) { mount_point = strdup(other.mount_point); }
158   if (other.mount_command) { mount_command = strdup(other.mount_command); }
159   if (other.unmount_command) {
160     unmount_command = strdup(other.unmount_command);
161   }
162   if (other.write_part_command) {
163     write_part_command = strdup(other.write_part_command);
164   }
165   if (other.free_space_command) {
166     free_space_command = strdup(other.free_space_command);
167   }
168   count = other.count;
169   multiplied_device_resource = other.multiplied_device_resource;
170   multiplied_device_resource_base_name
171       = other.multiplied_device_resource_base_name;
172   dev = other.dev;
173   changer_res = other.changer_res;
174 }
175 
operator =(const DeviceResource & rhs)176 DeviceResource& DeviceResource::operator=(const DeviceResource& rhs)
177 {
178   BareosResource::operator=(rhs);
179   media_type = rhs.media_type;
180   archive_device_string = rhs.archive_device_string;
181   device_options = rhs.device_options;
182   diag_device_name = rhs.diag_device_name;
183   changer_name = rhs.changer_name;
184   changer_command = rhs.changer_command;
185   alert_command = rhs.alert_command;
186   spool_directory = rhs.spool_directory;
187   dev_type = rhs.dev_type;
188   label_type = rhs.label_type;
189   autoselect = rhs.autoselect;
190   norewindonclose = rhs.norewindonclose;
191   drive_tapealert_enabled = rhs.drive_tapealert_enabled;
192   drive_crypto_enabled = rhs.drive_crypto_enabled;
193   query_crypto_status = rhs.query_crypto_status;
194   collectstats = rhs.collectstats;
195   eof_on_error_is_eot = rhs.eof_on_error_is_eot;
196   drive = rhs.drive;
197   drive_index = rhs.drive_index;
198   memcpy(cap_bits, rhs.cap_bits, CAP_BYTES);
199   max_changer_wait = rhs.max_changer_wait;
200   max_rewind_wait = rhs.max_rewind_wait;
201   max_open_wait = rhs.max_open_wait;
202   max_open_vols = rhs.max_open_vols;
203   label_block_size = rhs.label_block_size;
204   min_block_size = rhs.min_block_size;
205   max_block_size = rhs.max_block_size;
206   max_network_buffer_size = rhs.max_network_buffer_size;
207   max_concurrent_jobs = rhs.max_concurrent_jobs;
208   autodeflate_algorithm = rhs.autodeflate_algorithm;
209   autodeflate_level = rhs.autodeflate_level;
210   autodeflate = rhs.autodeflate;
211   autoinflate = rhs.autoinflate;
212   vol_poll_interval = rhs.vol_poll_interval;
213   max_volume_size = rhs.max_volume_size;
214   max_file_size = rhs.max_file_size;
215   volume_capacity = rhs.volume_capacity;
216   max_spool_size = rhs.max_spool_size;
217   max_job_spool_size = rhs.max_job_spool_size;
218 
219   max_part_size = rhs.max_part_size;
220   mount_point = rhs.mount_point;
221   mount_command = rhs.mount_command;
222   unmount_command = rhs.unmount_command;
223   write_part_command = rhs.write_part_command;
224   free_space_command = rhs.free_space_command;
225   count = rhs.count;
226   multiplied_device_resource = rhs.multiplied_device_resource;
227   multiplied_device_resource_base_name
228       = rhs.multiplied_device_resource_base_name;
229   dev = rhs.dev;
230   changer_res = rhs.changer_res;
231   temporarily_swapped_numbered_name = rhs.temporarily_swapped_numbered_name;
232 
233   return *this;
234 }
235 
236 
PrintConfig(OutputFormatterResource & send,const ConfigurationParser &,bool hide_sensitive_data,bool verbose)237 bool DeviceResource::PrintConfig(OutputFormatterResource& send,
238                                  const ConfigurationParser&,
239                                  bool hide_sensitive_data,
240                                  bool verbose)
241 {
242   if (multiplied_device_resource) {
243     if (multiplied_device_resource == this) {
244       MultipliedDeviceRestoreBaseName();
245       BareosResource::PrintConfig(send, *my_config, hide_sensitive_data,
246                                   verbose);
247       MultipliedDeviceRestoreNumberedName();
248     } else {
249       /* do not print the multiplied devices */
250       return false;
251     }
252   } else {
253     BareosResource::PrintConfig(send, *my_config, hide_sensitive_data, verbose);
254   }
255   return true;
256 }
257 
258 
MultipliedDeviceRestoreBaseName()259 void DeviceResource::MultipliedDeviceRestoreBaseName()
260 {
261   temporarily_swapped_numbered_name = resource_name_;
262   resource_name_
263       = const_cast<char*>(multiplied_device_resource_base_name.c_str());
264 }
265 
MultipliedDeviceRestoreNumberedName()266 void DeviceResource::MultipliedDeviceRestoreNumberedName()
267 {
268   /* call MultipliedDeviceRestoreBaseName() before */
269   ASSERT(temporarily_swapped_numbered_name);
270 
271   resource_name_ = temporarily_swapped_numbered_name;
272   temporarily_swapped_numbered_name = nullptr;
273 }
274 
CreateAndAssignSerialNumber(uint16_t number)275 void DeviceResource::CreateAndAssignSerialNumber(uint16_t number)
276 {
277   if (multiplied_device_resource_base_name.empty()) {
278     /* save the original name which is
279      * the base name for multiplied devices */
280     multiplied_device_resource_base_name = resource_name_;
281   }
282 
283   std::string tmp_name = multiplied_device_resource_base_name;
284 
285   char b[4 + 1];
286   ::sprintf(b, "%04d", number < 10000 ? number : 9999);
287   tmp_name += b;
288 
289   free(resource_name_);
290   resource_name_ = strdup(tmp_name.c_str());
291 }
292 
Validate()293 bool DeviceResource::Validate()
294 {
295   if (max_block_size > 0 && dev_type != DeviceType::B_TAPE_DEV) {
296     my_config->AddWarning(
297         "Setting 'Maximum Block Size' on a non-tape device is unsupported");
298   }
299   if (dev_type == DeviceType::B_RADOS_DEV) {
300     my_config->AddWarning("The Rados Storage Backend Device is deprecated");
301   }
302   return true;
303 }
304 
305 } /* namespace storagedaemon  */
306