view release on metacpan or search on metacpan
unless ($jio->installed) {
# Ask the user if they'd like to install this; if not, then exit
$builder->y_n('libjio was not found on your system. Install it now?', 'y')
or exit;
$builder->notes(build_libjio => 1);
# Ask the user what 'make' program to invoke
my $make;
if (exists($ENV{MAKE}) && length($ENV{MAKE})) {
$make = $ENV{MAKE};
}
else {
use Config '%Config';
$make = $Config{make};
# Probe for GNU Make (useful on BSD/Unix variants)
if ($make eq 'make' && grep { -x $_ . '/gmake' } @PATH) {
$make = 'gmake';
warn 'your system is a BSD variant but gmake was not found'
lib/Alien/Libjio.pm view on Meta::CPAN
return <$read>;
}
return (undef, <$read>) if wantarray;
return;
}
sub _try_pkg_config {
my ($self) = @_;
my ($value, $err) = _get_pc('cflags');
return unless (defined $value && length $value);
#if (defined $err && length $err) {
# #warn "Problem with pkg-config; using ExtUtils::Liblist instead\n";
# return;
#}
$self->{installed} = 1;
$self->{method} = 'pkg-config';
# pkg-config returns things with a newline, so remember to remove it
$self->{cflags} = [ split(' ', $value) ];
$self->{ldflags} = [ split(' ', _get_pc('libs')) ];
lib/Alien/Libjio.pm view on Meta::CPAN
return 1;
}
sub _try_liblist {
my ($self) = @_;
use ExtUtils::Liblist ();
local $SIG{__WARN__} = sub { }; # mask warnings
my (undef, undef, $ldflags, $ldpath) = ExtUtils::Liblist->ext('-ljio');
return unless (defined($ldflags) && length($ldflags));
$self->{installed} = 1;
$self->{method} = 'ExtUtils::Liblist';
# Empty out cflags; initialize it
$self->{cflags} = [];
my $read;
my $pid = open3(undef, $read, undef, 'getconf', 'LFS_CFLAGS');
libjio/bindings/preload/libjio_preload.c view on Meta::CPAN
static int (*c_close)(int fd);
static int (*c_unlink)(const char *pathname);
static ssize_t (*c_read)(int fd, void *buf, size_t count);
static ssize_t (*c_pread)(int fd, void *buf, size_t count, off_t offset);
static ssize_t (*c_pread64)(int fd, void *buf, size_t count, off64_t offset);
static ssize_t (*c_readv)(int fd, const struct iovec *vector, int count);
static ssize_t (*c_write)(int fd, const void *buf, size_t count);
static ssize_t (*c_pwrite)(int fd, const void *buf, size_t count, off_t offset);
static ssize_t (*c_pwrite64)(int fd, const void *buf, size_t count, off64_t offset);
static ssize_t (*c_writev)(int fd, const struct iovec *vector, int count);
static int (*c_ftruncate)(int fd, off_t length);
static int (*c_ftruncate64)(int fd, off64_t length);
static off_t (*c_lseek)(int fd, off_t offset, int whence);
static off64_t (*c_lseek64)(int fd, off64_t offset, int whence);
static int (*c_fsync)(int fd);
static int (*c_dup)(int oldfd);
static int (*c_dup2)(int oldfd, int newfd);
/* file descriptor table, to translate fds to jfs */
struct fd_entry {
int fd;
libjio/bindings/preload/libjio_preload.c view on Meta::CPAN
mkwrapper(ssize_t, writev, (int fd, const struct iovec *vector, int count),
(fd, vector, count), (fs, vector, count) );
mkwrapper(off_t, lseek, (int fd, off_t offset, int whence),
(fd, offset, whence), (fs, offset, whence) );
/* libjio defines jtruncate and jsync, not jftruncate and jfsync, which breaks
* the macro; so we add a nice #define to unbreak it */
#define jftruncate jtruncate
mkwrapper(int, ftruncate, (int fd, off_t length),
(fd, length), (fs, length) );
#define jfsync jsync
mkwrapper(int, fsync, (int fd), (fd), (fs) );
/* 64-bit versions */
#define jpread64 jpread
mkwrapper(ssize_t, pread64, (int fd, void *buf, size_t count, off64_t offset),
(fd, buf, count, offset), (fs, buf, count, offset) );
#define jpwrite64 jpwrite
mkwrapper(ssize_t, pwrite64,
(int fd, const void *buf, size_t count, off64_t offset),
(fd, buf, count, offset), (fs, buf, count, offset) );
#define jlseek64 jlseek
mkwrapper(off64_t, lseek64, (int fd, off64_t offset, int whence),
(fd, offset, whence), (fs, offset, whence) );
#define jftruncate64 jtruncate
mkwrapper(int, ftruncate64, (int fd, off64_t length),
(fd, length), (fs, length) );
libjio/doc/guide.rst view on Meta::CPAN
Definitions
-----------
This is a library which provides a transaction-oriented I/O API.
We say this is a transaction-oriented API because we make transactions the
center of our operations, and journaled because we use a journal (which takes
the form of a directory with files on it) to guarantee coherency even after a
crash at any point.
In this document, we think of a transaction as a list of *(buffer, length,
offset)* to be written to a file. That triplet is called an *operation*, so we
can say that a transaction represents an ordered group of operations on the
same file.
The act of *committing* a transaction means writing all the elements of that
list; and *rolling back* means to undo a previous commit, and leave the data
just as it was before doing the commit.
The library provides several guarantees, the most relevant and useful being
that at any point of time, even if the machine crash horribly, a transaction
libjio/doc/libjio.rst view on Meta::CPAN
The transaction file
~~~~~~~~~~~~~~~~~~~~
The transaction file is composed of three main parts: the header, the
operations, and the trailer.
The header holds basic information about the transaction itself, including the
version, the transaction ID, and its flags.
Then the operation part has all the operations one after the other, prepending
the operation data with a per-operation header that includes the length of the
data and the offset of the file where it should be applied, and then the data
itself.
Finally, the trailer contains the number of operations included in it and a
checksum of the whole file. Both fields are used to detect broken or corrupted
transactions.
The commit procedure
--------------------
libjio/libjio/libjio.3 view on Meta::CPAN
allocated by the library; all disk operations are performed by the other two
functions.
You can add multiple read and write operations to a transaction, and they will
be applied in order.
.B jtrans_add_w()
is used to add write operations to a transaction, and it takes the same
parameters as
.BR pwrite() :
a buffer, its length and the offset where it should be applied, and adds it to
the transaction. The buffer is copied internally and can be free()d right
after this function returns.
.B jtrans_add_r()
is used to add read operations to a transaction, and it takes the same
parameters as
.BR pread() :
a buffer, its length and the offset where it should read from, and adds it to
the transaction. Note that if there is not enough data in the file to read
the specified amount of bytes, the commit will fail, so do not attempt to read
beyond EOF (you can use jread() for that purpose).
.B jtrans_commit()
commits the given transaction to disk. After it has returned, write operations
have been saved to the disk, and read operations have been read from it. The
commit operation is atomic with regards to other read or write operations on
different processes, as long as they all access it via libjio. It returns the
number 0 on success, -1 if there was an error but atomic warantees were
libjio/libjio/libjio.h view on Meta::CPAN
* @param fs open file the transaction will apply to
* @param flags transaction flags
* @returns a new transaction (must be freed using jtrans_free())
* @see jtrans_free()
* @ingroup basic
*/
jtrans_t *jtrans_new(jfs_t *fs, unsigned int flags);
/** Add a write operation to a transaction.
*
* A write operation consists of a buffer, its length, and the offset to write
* it to.
*
* The file will not be touched (not even locked) until commit time, where the
* first count bytes of buf will be written at offset.
*
* Operations will be applied in order, and overlapping operations are
* permitted, in which case the latest one will prevail.
*
* The buffer will be copied internally and can be free()d right after this
* function returns.
libjio/libjio/libjio.h view on Meta::CPAN
* @param buf buffer to write
* @param count how many bytes from the buffer to write
* @param offset offset to write at
* @returns 0 on success, -1 on error
* @ingroup basic
*/
int jtrans_add_w(jtrans_t *ts, const void *buf, size_t count, off_t offset);
/** Add a read operation to a transaction.
*
* An operation consists of a buffer, its length, and the offset to read it
* from.
*
* The file will not be touched (not even locked) until commit time, where the
* first count bytes at offset will be read into buf.
*
* Note that if there is not enough data in the file to read the specified
* amount of bytes, the commit will fail, so do not attempt to read beyond EOF
* (you can use jread() for that purpose).
*
* Operations will be applied in order, and overlapping operations are
libjio/libjio/libjio.h view on Meta::CPAN
*
* @param fs file to write to
* @param vector buffers used to read the data from
* @param count maximum number of bytes to write
* @returns number of bytes written on success, or -1 on error
* @see writev(2)
* @ingroup unix
*/
ssize_t jwritev(jfs_t *fs, const struct iovec *vector, int count);
/** Truncates the file to the given length. Works just like UNIX ftruncate(2).
*
* @param fs file to truncate
* @param length lenght to truncate to
* @returns 0 on success, -1 on error
* @see ftruncate(2)
* @ingroup unix
*/
int jtruncate(jfs_t *fs, off_t length);
/** Reposition read/write file offset. Works just like UNIX lseek(2).
*
* @param fs file to change the offset to
* @param offset offset to set
* @param whence where to count offset from, can be SEEK_SET to count from the
* beginning of the file, SEEK_CUR to count from the current position, or
* SEEK_END to count from the end.
* @returns the new offset counted from the beginning of the file, or -1 on
* error.
libjio/libjio/trans.h view on Meta::CPAN
/** Transaction flags */
uint32_t flags;
/** Number of read operations in the list */
unsigned int numops_r;
/** Number of write operations in the list */
unsigned int numops_w;
/** Sum of the lengths of the write operations */
size_t len_w;
/** Lock that protects the list of operations */
pthread_mutex_t lock;
/** List of operations */
struct operation *op;
};
/** Possible operation directions */
libjio/libjio/trans.h view on Meta::CPAN
};
/** A single operation */
struct operation {
/** Is the region locked? */
int locked;
/** Operation's offset */
off_t offset;
/** Data length, in bytes */
size_t len;
/** Data buffer */
void *buf;
/** Direction */
enum op_direction direction;
/** Previous data length (only if direction == D_WRITE) */
size_t plen;
/** Previous data (only if direction == D_WRITE) */
void *pdata;
/** Previous operation */
struct operation *prev;
/** Next operation */
struct operation *next;
libjio/libjio/unix.c view on Meta::CPAN
exit:
pthread_mutex_unlock(&(fs->lock));
jtrans_free(ts);
return (rv >= 0) ? sum : rv;
}
/* Truncate a file. Be careful with this */
int jtruncate(struct jfs *fs, off_t length)
{
int rv;
/* lock from length to the end of file */
plockf(fs->fd, F_LOCKW, length, 0);
rv = ftruncate(fs->fd, length);
plockf(fs->fd, F_UNLOCK, length, 0);
return rv;
}
/* lseek() wrapper */
off_t jlseek(struct jfs *fs, off_t offset, int whence)
{
off_t rv;
pthread_mutex_lock(&(fs->lock));
libjio/tests/behaviour/t_normal.py view on Meta::CPAN
n = f.name
jf.write(c1)
jf.write(c2)
assert content(n) == c1 + c2
fsck_verify(n)
cleanup(n)
def test_n20():
"jtrans_add_w of 0 length"
f, jf = bitmp()
n = f.name
t = jf.new_trans()
try:
t.add_w('', 80)
except IOError:
pass
else: