Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Tweak layout and naming.
- Always use the virtual d_open method.
- Open system call is called with 2 or 3 arguments but they are named
  path, oflag and mode so don't use mode for what is normally is
  called oflag as that could be misinterpretted as being the mode
  argument.
- Tweak layout of comments and use spaces around or-ed values for
  readability.
- Abstract truncate function to device specific truncate function.
- Rename ST_APPEND to ST_APPENDREADY and ST_READ to ST_READREADY
  to work around namespace collision of ST_APPEND in statvfs.h
  on Linux.
- Move device abstraction into src/stored/backends
  • Loading branch information
Marco van Wieringen committed Feb 25, 2014
1 parent 860aaeb commit c05f55d
Show file tree
Hide file tree
Showing 20 changed files with 550 additions and 274 deletions.
20 changes: 12 additions & 8 deletions src/stored/Makefile.in
Expand Up @@ -2,7 +2,7 @@
@MCOMMON@

srcdir = @srcdir@
VPATH = @srcdir@
VPATH = @srcdir@:backends
.PATH: @srcdir@

sd_group=@sd_group@
Expand All @@ -27,48 +27,52 @@ GNUTLS_LIBS_NONSHARED = @GNUTLS_LIBS_NONSHARED@
first_rule: all
dummy:

DEVICE_API_SRCS = unix_file_device.c \
unix_tape_device.c \
vtape.c

# bareos-sd
SDSRCS = acquire.c ansi_label.c append.c askdir.c authenticate.c \
autochanger.c block.c bsr.c butil.c crc32.c dev.c device.c \
dir_cmd.c ebcdic.c fd_cmds.c job.c label.c lock.c mac.c mount.c \
ndmp_tape.c read_record.c read.c record.c reserve.c scan.c sd_cmds.c \
sd_plugins.c spool.c status.c stored_conf.c stored.c vol_mgr.c vtape.c \
wait.c unix_device.c
sd_plugins.c spool.c status.c stored_conf.c stored.c vol_mgr.c \
wait.c $(DEVICE_API_SRCS)
SDOBJS = $(SDSRCS:.c=.o)

# btape
TAPESRCS = acquire.c ansi_label.c autochanger.c block.c btape.c bsr.c \
butil.c crc32.c dev.c device.c ebcdic.c label.c lock.c mount.c \
read_record.c record.c reserve.c scan.c sd_plugins.c spool.c \
stored_conf.c vol_mgr.c vtape.c wait.c unix_device.c
stored_conf.c vol_mgr.c wait.c $(DEVICE_API_SRCS)
TAPEOBJS = $(TAPESRCS:.c=.o)

# bls
BLSSRCS = acquire.c ansi_label.c autochanger.c block.c bls.c bsr.c \
butil.c crc32.c dev.c device.c ebcdic.c label.c lock.c mount.c \
read_record.c record.c reserve.c scan.c sd_plugins.c spool.c \
stored_conf.c vol_mgr.c vtape.c wait.c unix_device.c
stored_conf.c vol_mgr.c wait.c $(DEVICE_API_SRCS)
BLSOBJS = $(BLSSRCS:.c=.o)

# bextract
BEXTSRCS = acquire.c ansi_label.c autochanger.c bextract.c block.c bsr.c \
butil.c crc32.c dev.c device.c ebcdic.c label.c lock.c mount.c \
read_record.c record.c reserve.c scan.c sd_plugins.c spool.c \
stored_conf.c vol_mgr.c vtape.c wait.c unix_device.c
stored_conf.c vol_mgr.c wait.c $(DEVICE_API_SRCS)
BEXTOBJS = $(BEXTSRCS:.c=.o)

# bscan
SCNSRCS = acquire.c ansi_label.c autochanger.c block.c bscan.c bsr.c \
butil.c crc32.c dev.c device.c ebcdic.c label.c lock.c mount.c \
read_record.c record.c reserve.c scan.c sd_plugins.c spool.c \
stored_conf.c vol_mgr.c vtape.c wait.c unix_device.c
stored_conf.c vol_mgr.c wait.c $(DEVICE_API_SRCS)
SCNOBJS = $(SCNSRCS:.c=.o)

# bcopy
COPYSRCS = acquire.c ansi_label.c autochanger.c bcopy.c block.c bsr.c \
butil.c crc32.c dev.c device.c ebcdic.c label.c lock.c mount.c \
read_record.c record.c reserve.c scan.c sd_plugins.c spool.c \
stored_conf.c vol_mgr.c vtape.c wait.c unix_device.c
stored_conf.c vol_mgr.c wait.c $(DEVICE_API_SRCS)
COPYOBJS = $(COPYSRCS:.c=.o)

SD_LIBS += @CAP_LIBS@
Expand Down
2 changes: 1 addition & 1 deletion src/stored/acquire.c
Expand Up @@ -291,7 +291,7 @@ bool acquire_device_for_read(DCR *dcr)

/* Mount a specific volume and no other */
Dmsg0(rdbglvl, "calling dir_ask_sysop\n");
if (!dir_ask_sysop_to_mount_volume(dcr, ST_READ)) {
if (!dir_ask_sysop_to_mount_volume(dcr, ST_READREADY)) {
goto get_out; /* error return */
}

Expand Down
2 changes: 1 addition & 1 deletion src/stored/askdir.c
Expand Up @@ -625,7 +625,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr, int mode)
if (!dev->poll && (status == W_TIMEOUT || status == W_MOUNT)) {
const char *msg;

if (mode == ST_APPEND) {
if (mode == ST_APPENDREADY) {
msg = _("Please mount append Volume \"%s\" or label a new one for:\n"
" Job: %s\n"
" Storage: %s\n"
Expand Down
136 changes: 136 additions & 0 deletions src/stored/backends/unix_file_device.c
@@ -0,0 +1,136 @@
/*
BAREOS® - Backup Archiving REcovery Open Sourced
Copyright (C) 2013-2013 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
/*
* UNIX File API device abstraction.
*
* Marco van Wieringen, December 2013
*/

#include "bareos.h"
#include "stored.h"
#include "unix_file_device.h"

int unix_file_device::d_open(const char *pathname, int flags, int mode)
{
return ::open(pathname, flags, mode);
}

ssize_t unix_file_device::d_read(int fd, void *buffer, size_t count)
{
return ::read(fd, buffer, count);
}

ssize_t unix_file_device::d_write(int fd, const void *buffer, size_t count)
{
return ::write(fd, buffer, count);
}

int unix_file_device::d_close(int fd)
{
return ::close(fd);
}

int unix_file_device::d_ioctl(int fd, ioctl_req_t request, char *op)
{
return -1;
}

boffset_t unix_file_device::d_lseek(DCR *dcr, boffset_t offset, int whence)
{
return ::lseek(m_fd, offset, whence);
}

bool unix_file_device::d_truncate(DCR *dcr)
{
struct stat st;

if (ftruncate(m_fd, 0) != 0) {
berrno be;

Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), print_name(), be.bstrerror());
return false;
}

/*
* Check for a successful ftruncate() and issue a work-around for devices
* (mostly cheap NAS) that don't support truncation.
* Workaround supplied by Martin Schmid as a solution to bug #1011.
* 1. close file
* 2. delete file
* 3. open new file with same mode
* 4. change ownership to original
*/
if (fstat(m_fd, &st) != 0) {
berrno be;

Mmsg2(errmsg, _("Unable to stat device %s. ERR=%s\n"), print_name(), be.bstrerror());
return false;
}

if (st.st_size != 0) { /* ftruncate() didn't work */
POOL_MEM archive_name(PM_FNAME);

pm_strcpy(archive_name, dev_name);
if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) {
pm_strcat(archive_name, "/");
}
pm_strcat(archive_name, dcr->VolumeName);

Mmsg2(errmsg, _("Device %s doesn't support ftruncate(). Recreating file %s.\n"),
print_name(), archive_name.c_str());

/*
* Close file and blow it away
*/
::close(m_fd);
::unlink(archive_name.c_str());

/*
* Recreate the file -- of course, empty
*/
set_mode(CREATE_READ_WRITE);
if ((m_fd = ::open(archive_name.c_str(), oflags, st.st_mode)) < 0) {
berrno be;

dev_errno = errno;
Mmsg2(errmsg, _("Could not reopen: %s, ERR=%s\n"), archive_name.c_str(), be.bstrerror());
Dmsg1(100, "reopen failed: %s", errmsg);
Emsg0(M_FATAL, 0, errmsg);
return false;
}

/*
* Reset proper owner
*/
chown(archive_name.c_str(), st.st_uid, st.st_gid);
}

return true;
}

unix_file_device::~unix_file_device()
{
}

unix_file_device::unix_file_device()
{
m_fd = -1;
}
47 changes: 47 additions & 0 deletions src/stored/backends/unix_file_device.h
@@ -0,0 +1,47 @@
/*
BAREOS® - Backup Archiving REcovery Open Sourced
Copyright (C) 2013-2013 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation, which is
listed in the file LICENSE.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
/*
* UNIX File API device abstraction.
*
* Marco van Wieringen, December 2013
*/

#ifndef UNIX_FILE_DEVICE_H
#define UNIX_FILE_DEVICE_H

class unix_file_device: public DEVICE {
public:
unix_file_device();
~unix_file_device();

/*
* Interface from DEVICE
*/
int d_close(int);
int d_open(const char *pathname, int flags, int mode);
int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL);
boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence);
ssize_t d_read(int fd, void *buffer, size_t count);
ssize_t d_write(int fd, const void *buffer, size_t count);
bool d_truncate(DCR *dcr);
};

#endif /* UNIX_FILE_DEVICE_H */
37 changes: 23 additions & 14 deletions src/stored/unix_device.c → src/stored/backends/unix_tape_device.c
Expand Up @@ -18,50 +18,59 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
/*
* UNIX Tape API device abstraction.
*
* Marco van Wieringen, December 2013
*/

#include "bareos.h"
#include "stored.h"
#include "unix_device.h"
#include "unix_tape_device.h"

int unix_device::d_open(const char *pathname, int flags)
int unix_tape_device::d_open(const char *pathname, int flags, int mode)
{
return ::open(pathname, flags);
return ::open(pathname, flags, mode);
}

ssize_t unix_device::d_read(int fd, void *buffer, size_t count)
ssize_t unix_tape_device::d_read(int fd, void *buffer, size_t count)
{
return ::read(fd, buffer, count);
}

ssize_t unix_device::d_write(int fd, const void *buffer, size_t count)
ssize_t unix_tape_device::d_write(int fd, const void *buffer, size_t count)
{
return ::write(fd, buffer, count);
}

int unix_device::d_close(int fd)
int unix_tape_device::d_close(int fd)
{
return ::close(fd);
}

int unix_device::d_ioctl(int fd, ioctl_req_t request, char *op)
int unix_tape_device::d_ioctl(int fd, ioctl_req_t request, char *op)
{
return ::ioctl(fd, request, op);
}

boffset_t unix_device::lseek(DCR *dcr, boffset_t offset, int whence)
boffset_t unix_tape_device::d_lseek(DCR *dcr, boffset_t offset, int whence)
{
switch (dev_type) {
case B_FILE_DEV:
return ::lseek(m_fd, offset, whence);
}
return -1;
}

unix_device::~unix_device()
bool unix_tape_device::d_truncate(DCR *dcr)
{
/*
* Maybe we should rewind and write and eof ????
*/
return true; /* We don't really truncate tapes */
}

unix_tape_device::~unix_tape_device()
{
}

unix_device::unix_device()
unix_tape_device::unix_tape_device()
{
m_fd = -1;
}
Expand Up @@ -19,25 +19,29 @@
02110-1301, USA.
*/
/*
* UNIX API device abstraction.
*
* Marco van Wieringen, December 2013
*/

#ifndef WIN32_DISK_DEVICE_H
#define WIN32_DISK_DEVICE_H
#ifndef UNIX_TAPE_DEVICE_H
#define UNIX_TAPE_DEVICE_H

class unix_device: public DEVICE {
class unix_tape_device: public DEVICE {
public:
unix_device();
~unix_device();
unix_tape_device();
~unix_tape_device();

/*
* Interface from DEVICE
*/
int d_close(int);
int d_open(const char *pathname, int flags);
int d_ioctl(int fd, ioctl_req_t request, char *mt=NULL);
boffset_t lseek(DCR *dcr, boffset_t offset, int whence);
int d_open(const char *pathname, int flags, int mode);
int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL);
boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence);
ssize_t d_read(int fd, void *buffer, size_t count);
ssize_t d_write(int fd, const void *buffer, size_t count);
bool d_truncate(DCR *dcr);
};

#endif /* WIN32_DISK_DEVICE_H */
#endif /* UNIX_TAPE_DEVICE_H */

0 comments on commit c05f55d

Please sign in to comment.