Hi,
its disappointing to see zero reactions on my mail(s) on this topic. See
bottom of this posting for original mail and description of my problems (sorry
for TOFU posting).
Restoring device nodes prior to restoring block device data (this is what
bacula does) does not make any sense in any scenario I can think of, at least
for modern Linux systems (granted, I don't know too much about other unix
flavors). udev and/or the kernel handle creation of block device nodes for all
available block devices, and have been doing so for quite a while
(udev, devfs, predecessors, ...).
When backing up a device such as, say, /dev/sda5, a restore will never be
possible when /dev/sda5 does not pre-exist (Linux will not accept the
restore). In case of LVM block devices, things become worse; Bacula will
create a device node with the name of the backup device, and will give it the
same major/minor numbers. However, that major/minor number pair may be
allocated to a new, different LV at restore time. Restoring the data will
result in overwriting of a different LV.
Creation of device nodes thus is a bad choice for our scenarios. If the device
node pre-exists, restore to that node is fine, of course. Due to that, restore
can/should be done to a file "image" of the respective device, if the device
node did not pre-exist. However, restoring to a (possibly rather small) root
file system may quickly overflow the FS. This is especially true for our
personal requirements of bacula, although it obviously is not for many other
scenarios. I am yet unsure of the value of a device image in /dev ...
I am attaching a patch for bacula 5.0.3 that we will be using in the future
(being aware of the fact that this patch only reflects our constraints, which
may very well be quite different from others'). It will
a) never create block or character device nodes
b) create regular files and dump data to them while restoring to a location
outside of the root filesystem ("where=/")
c) give an error when restoring to the system root file system while the
respective device node does not exist
Feel free to use the patch in any way you like. If you want to take it
upstream -- I have filled in the FLA in the past.
Thx
Bastian
Am Mittwoch, 2. März 2011, 17:40:30 schrieb Bastian Friedrich:
> bacula is able to back up data from block devices by listing them as
> dedicated files in filesets. During restore, data is expected to be dumped
> back to these devices.
>
> However, this results in ambiguities when restoring to a location ("where"
> statement) other than the system root. E.g., restoring to a temporary
> directory/location (I'm using /tmp in this example) results in the device
> file being created in the respective location, and the data being fed to
> that device -- possibly resulting the data being written to the "original"
> space. E.g., if a device /dev/sda1 was backed up, a device file
> /tmp/dev/sda1 will be created with the major/minor pair of /dev/sda1 --
> and data being written to that device file will overwrite the system's
> /dev/sda1 -- not in an alternative location, as the user might expect.
>
> Interestingly, if a (file!) /tmp/dev/sda1 pre-exists, data is written into
> that file; the block device is not recreated. That file can e.g. be an
> empty file (touch /tmp/dev/sda1), or a loopback device (dd if=/dev/zero
> of=foo...; mknod /tmp/dev/sda1 b 7 1; losetup /tmp/dev/sda1 foo).
>
> I am unhappy with that situation; restoring with a given "where" location
> should never ever write data into the system's devices. At the same time, I
> was only able to restore data that was originally stored in a device to a
> file by the "hack" described above.
>
> As a side note, interestingly, the linux kernel happily accepted data for a
> block device that it did not have an appropriate module for during a
> restore. I was handling DRBD devices; after a backup of a DRBD device on
> one machine, I did not encounter any error messages on a machine that did
> not have an appropriate DRBD setup during restore. Data was never
> restored, however.
>
> What do you think? Is the behavior as it is the way you'd expect it to be?
> Would you rather think that the current behavior should be changed and
> documented in a better way?
>
> >From my point of view, it would be sensible to
>
> a) _always_ create files (instead of block devices) for restored data when
> an alternative location is given during restore
> and/or
> b) having a separate restore flag ("dump to file" vs. "dump to device") for
> block device restore behavior
>
> Thx
> Bastian
--
Collax GmbH . Basler Str. 115a . 79115 Freiburg . Germany
p: +49 (0) 89-990 157-28 www.collax.com
Geschäftsführer: Bernd Bönte, Boris Nalbach
AG München HRB 173695. Ust.-IdNr: DE270819312
diff -uNr bacula-5.0.3.ori/src/findlib/create_file.c bacula-5.0.3/src/findlib/create_file.c
--- bacula-5.0.3.ori/src/findlib/create_file.c 2010-08-05 16:29:51.000000000 +0200
+++ bacula-5.0.3/src/findlib/create_file.c 2011-06-16 14:09:40.000000000 +0200
@@ -79,6 +79,8 @@
bool exists = false;
struct stat mstatp;
+ bool isOnRoot;
+
bfd->reparse_point = false;
if (is_win32_stream(attr->data_stream)) {
set_win32_backup(bfd);
@@ -230,6 +232,9 @@
case FT_RAW: /* Bacula raw device e.g. /dev/sda1 */
case FT_FIFO: /* Bacula fifo to save data */
case FT_SPEC:
+ flags = O_WRONLY | O_BINARY;
+
+ isOnRoot = (strcmp(attr->fname, attr->ofname) == 0) ? 1 : 0;
if (S_ISFIFO(attr->statp.st_mode)) {
Dmsg1(400, "Restore fifo: %s\n", attr->ofname);
if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) {
@@ -248,6 +253,17 @@
} else if (S_ISPORT(attr->statp.st_mode)) {
Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname);
#endif
+ } else if ((S_ISBLK(attr->statp.st_mode) || (S_ISCHR(attr->statp.st_mode))) && !exists && isOnRoot) {
+ /*
+ * Fatal: Restoring a device on root-file system, but device node does not exist.
+ * Should not create a dump file.
+ */
+ Qmsg1(jcr, M_ERROR, 0, _("Device restore on root failed, device %s missing.\n"),
+ attr->fname);
+ return CF_ERROR;
+ } else if (S_ISBLK(attr->statp.st_mode) || S_ISCHR(attr->statp.st_mode)) {
+ Dmsg1(400, "Restoring a device as a file: %s\n", attr->ofname);
+ flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
} else {
Dmsg1(400, "Restore node: %s\n", attr->ofname);
if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
@@ -266,7 +282,6 @@
if (attr->type == FT_RAW || attr->type == FT_FIFO) {
btimer_t *tid;
Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname);
- flags = O_WRONLY | O_BINARY;
/* Timeout open() in 60 seconds */
if (attr->type == FT_FIFO) {
Dmsg0(400, "Set FIFO timer\n");
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Bacula-devel mailing list
Bacula-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-devel