parent
19a0102181
commit
54e47cf729
|
@ -3,19 +3,19 @@ if USE_CAPS
|
|||
bin_PROGRAMS += IOR MDTEST
|
||||
endif
|
||||
|
||||
noinst_HEADERS = ior.h utilities.h parse_options.h aiori.h iordef.h getopt/optlist.h ior-internal.h option.h
|
||||
noinst_HEADERS = ior.h utilities.h parse_options.h aiori.h iordef.h ior-internal.h option.h
|
||||
|
||||
extraSOURCES = aiori.c aiori-DUMMY.c
|
||||
extraLDADD =
|
||||
extraLDFLAGS =
|
||||
extraCPPFLAGS =
|
||||
|
||||
ior_SOURCES = ior-main.c ior.c utilities.c parse_options.c getopt/optlist.c ior-output.c option.c
|
||||
ior_SOURCES = ior-main.c ior.c utilities.c parse_options.c ior-output.c option.c
|
||||
ior_LDFLAGS =
|
||||
ior_LDADD =
|
||||
ior_CPPFLAGS =
|
||||
|
||||
mdtest_SOURCES = mdtest-main.c mdtest.c utilities.c getopt/optlist.c option.c
|
||||
mdtest_SOURCES = mdtest-main.c mdtest.c utilities.c option.c
|
||||
mdtest_LDFLAGS =
|
||||
mdtest_LDADD =
|
||||
mdtest_CPPFLAGS =
|
||||
|
|
|
@ -80,9 +80,9 @@ static void DUMMY_Delete(char *testFileName, IOR_param_t * param)
|
|||
}
|
||||
}
|
||||
|
||||
static void DUMMY_SetVersion(IOR_param_t * test)
|
||||
static char * DUMMY_getVersion()
|
||||
{
|
||||
sprintf(test->apiVersion, "DUMMY-0.5");
|
||||
return "0.5";
|
||||
}
|
||||
|
||||
static IOR_offset_t DUMMY_GetFileSize(IOR_param_t * test, MPI_Comm testComm, char *testFileName)
|
||||
|
@ -136,7 +136,7 @@ ior_aiori_t dummy_aiori = {
|
|||
DUMMY_Xfer,
|
||||
DUMMY_Close,
|
||||
DUMMY_Delete,
|
||||
DUMMY_SetVersion,
|
||||
DUMMY_getVersion,
|
||||
DUMMY_Fsync,
|
||||
DUMMY_GetFileSize,
|
||||
DUMMY_statfs,
|
||||
|
|
|
@ -42,7 +42,7 @@ ior_aiori_t mmap_aiori = {
|
|||
.xfer = MMAP_Xfer,
|
||||
.close = MMAP_Close,
|
||||
.delete = POSIX_Delete,
|
||||
.set_version = aiori_set_version,
|
||||
.get_version = aiori_get_version,
|
||||
.fsync = MMAP_Fsync,
|
||||
.get_file_size = POSIX_GetFileSize,
|
||||
};
|
||||
|
|
|
@ -38,7 +38,7 @@ static void *MPIIO_Open(char *, IOR_param_t *);
|
|||
static IOR_offset_t MPIIO_Xfer(int, void *, IOR_size_t *,
|
||||
IOR_offset_t, IOR_param_t *);
|
||||
static void MPIIO_Close(void *, IOR_param_t *);
|
||||
static void MPIIO_SetVersion(IOR_param_t *);
|
||||
static char* MPIIO_GetVersion();
|
||||
static void MPIIO_Fsync(void *, IOR_param_t *);
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ ior_aiori_t mpiio_aiori = {
|
|||
.xfer = MPIIO_Xfer,
|
||||
.close = MPIIO_Close,
|
||||
.delete = MPIIO_Delete,
|
||||
.set_version = MPIIO_SetVersion,
|
||||
.get_version = MPIIO_GetVersion,
|
||||
.fsync = MPIIO_Fsync,
|
||||
.get_file_size = MPIIO_GetFileSize,
|
||||
.statfs = aiori_posix_statfs,
|
||||
|
@ -411,13 +411,16 @@ void MPIIO_Delete(char *testFileName, IOR_param_t * param)
|
|||
/*
|
||||
* Determine api version.
|
||||
*/
|
||||
static void MPIIO_SetVersion(IOR_param_t * test)
|
||||
static char* MPIIO_GetVersion()
|
||||
{
|
||||
int version, subversion;
|
||||
MPI_CHECK(MPI_Get_version(&version, &subversion),
|
||||
"cannot get MPI version");
|
||||
sprintf(test->apiVersion, "%s (version=%d, subversion=%d)",
|
||||
test->api, version, subversion);
|
||||
static char ver[1024] = {};
|
||||
if (ver){
|
||||
return ver;
|
||||
}
|
||||
int version, subversion;
|
||||
MPI_CHECK(MPI_Get_version(&version, &subversion), "cannot get MPI version");
|
||||
sprintf(ver, "(%d.%d)", version, subversion);
|
||||
return ver;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -67,7 +67,7 @@ ior_aiori_t ncmpi_aiori = {
|
|||
.xfer = NCMPI_Xfer,
|
||||
.close = NCMPI_Close,
|
||||
.delete = NCMPI_Delete,
|
||||
.set_version = NCMPI_SetVersion,
|
||||
.get_version = NCMPI_GetVersion,
|
||||
.fsync = NCMPI_Fsync,
|
||||
.get_file_size = NCMPI_GetFileSize,
|
||||
.statfs = aiori_posix_statfs,
|
||||
|
@ -341,9 +341,9 @@ static void NCMPI_Delete(char *testFileName, IOR_param_t * param)
|
|||
/*
|
||||
* Determine api version.
|
||||
*/
|
||||
static void NCMPI_SetVersion(IOR_param_t * test)
|
||||
static char* NCMPI_GetVersion()
|
||||
{
|
||||
sprintf(test->apiVersion, "%s (%s)", test->api, ncmpi_inq_libvers());
|
||||
return ncmpi_inq_libvers();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -78,7 +78,7 @@ ior_aiori_t posix_aiori = {
|
|||
.xfer = POSIX_Xfer,
|
||||
.close = POSIX_Close,
|
||||
.delete = POSIX_Delete,
|
||||
.set_version = aiori_set_version,
|
||||
.get_version = aiori_get_version,
|
||||
.fsync = POSIX_Fsync,
|
||||
.get_file_size = POSIX_GetFileSize,
|
||||
.statfs = aiori_posix_statfs,
|
||||
|
|
|
@ -49,7 +49,6 @@ static IOR_offset_t RADOS_Xfer(int, void *, IOR_size_t *,
|
|||
IOR_offset_t, IOR_param_t *);
|
||||
static void RADOS_Close(void *, IOR_param_t *);
|
||||
static void RADOS_Delete(char *, IOR_param_t *);
|
||||
static void RADOS_SetVersion(IOR_param_t *);
|
||||
static void RADOS_Fsync(void *, IOR_param_t *);
|
||||
static IOR_offset_t RADOS_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
||||
static int RADOS_StatFS(const char *, ior_aiori_statfs_t *, IOR_param_t *);
|
||||
|
@ -67,7 +66,7 @@ ior_aiori_t rados_aiori = {
|
|||
.xfer = RADOS_Xfer,
|
||||
.close = RADOS_Close,
|
||||
.delete = RADOS_Delete,
|
||||
.set_version = RADOS_SetVersion,
|
||||
.get_version = aiori_get_version,
|
||||
.fsync = RADOS_Fsync,
|
||||
.get_file_size = RADOS_GetFileSize,
|
||||
.statfs = RADOS_StatFS,
|
||||
|
@ -257,12 +256,6 @@ static void RADOS_Delete(char *testFileName, IOR_param_t * param)
|
|||
return;
|
||||
}
|
||||
|
||||
static void RADOS_SetVersion(IOR_param_t * test)
|
||||
{
|
||||
strcpy(test->apiVersion, test->api);
|
||||
return;
|
||||
}
|
||||
|
||||
static IOR_offset_t RADOS_GetFileSize(IOR_param_t * test, MPI_Comm testComm,
|
||||
char *testFileName)
|
||||
{
|
||||
|
|
|
@ -122,7 +122,6 @@ static IOR_offset_t EMC_Xfer(int, void*, IOR_size_t*, IOR_offset_t, IOR_param_t*
|
|||
static void EMC_Close(void*, IOR_param_t*);
|
||||
|
||||
static void S3_Delete(char*, IOR_param_t*);
|
||||
static void S3_SetVersion(IOR_param_t*);
|
||||
static void S3_Fsync(void*, IOR_param_t*);
|
||||
static IOR_offset_t S3_GetFileSize(IOR_param_t*, MPI_Comm, char*);
|
||||
|
||||
|
@ -138,7 +137,7 @@ ior_aiori_t s3_aiori = {
|
|||
.xfer = S3_Xfer,
|
||||
.close = S3_Close,
|
||||
.delete = S3_Delete,
|
||||
.set_version = S3_SetVersion,
|
||||
.get_version = aiori_get_version,
|
||||
.fsync = S3_Fsync,
|
||||
.get_file_size = S3_GetFileSize,
|
||||
};
|
||||
|
@ -183,7 +182,7 @@ ior_aiori_t s3_emc_aiori = {
|
|||
fflush(stdout); \
|
||||
MPI_Abort((PARAM)->testComm, -1); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
#define CURL_WARN(MSG, CURL_ERRNO) \
|
||||
do { \
|
||||
|
@ -192,7 +191,7 @@ ior_aiori_t s3_emc_aiori = {
|
|||
__FILE__, __LINE__); \
|
||||
fflush(stdout); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
|
||||
/* buffer is used to generate URLs, err_msgs, etc */
|
||||
|
@ -446,7 +445,7 @@ S3_Create_Or_Open_internal(char* testFileName,
|
|||
if ( n_to_n || (rank == 0) ) {
|
||||
|
||||
// rank0 handles truncate
|
||||
if ( needs_reset) {
|
||||
if ( needs_reset) {
|
||||
aws_iobuf_reset(param->io_buf);
|
||||
AWS4C_CHECK( s3_put(param->io_buf, testFileName) ); /* 0-length write */
|
||||
AWS4C_CHECK_OK( param->io_buf );
|
||||
|
@ -510,7 +509,7 @@ S3_Create_Or_Open_internal(char* testFileName,
|
|||
fprintf( stdout, "rank %d resetting\n",
|
||||
rank);
|
||||
}
|
||||
|
||||
|
||||
aws_iobuf_reset(param->io_buf);
|
||||
AWS4C_CHECK( s3_put(param->io_buf, testFileName) );
|
||||
AWS4C_CHECK_OK( param->io_buf );
|
||||
|
@ -641,7 +640,7 @@ EMC_Open( char *testFileName, IOR_param_t * param ) {
|
|||
/* In the EMC case, instead of Multi-Part Upload we can use HTTP
|
||||
* "byte-range" headers to write parts of a single object. This appears to
|
||||
* have several advantages over the S3 MPU spec:
|
||||
*
|
||||
*
|
||||
* (a) no need for a special "open" operation, to capture an "UploadID".
|
||||
* Instead we simply write byte-ranges, and the server-side resolves
|
||||
* any races, producing a single winner. In the IOR case, there should
|
||||
|
@ -808,7 +807,7 @@ S3_Xfer_internal(int access,
|
|||
printf("rank %d: part %d = ETag %s\n", rank, part_number, param->io_buf->eTag);
|
||||
}
|
||||
|
||||
// drop ptrs to <data_ptr>, in param->io_buf
|
||||
// drop ptrs to <data_ptr>, in param->io_buf
|
||||
aws_iobuf_reset(param->io_buf);
|
||||
}
|
||||
else { // use EMC's byte-range write-support, instead of MPU
|
||||
|
@ -830,7 +829,7 @@ S3_Xfer_internal(int access,
|
|||
AWS4C_CHECK ( s3_put(param->io_buf, file) );
|
||||
AWS4C_CHECK_OK( param->io_buf );
|
||||
|
||||
// drop ptrs to <data_ptr>, in param->io_buf
|
||||
// drop ptrs to <data_ptr>, in param->io_buf
|
||||
aws_iobuf_reset(param->io_buf);
|
||||
}
|
||||
|
||||
|
@ -867,7 +866,7 @@ S3_Xfer_internal(int access,
|
|||
ERR_SIMPLE(buff);
|
||||
}
|
||||
|
||||
// drop refs to <data_ptr>, in param->io_buf
|
||||
// drop refs to <data_ptr>, in param->io_buf
|
||||
aws_iobuf_reset(param->io_buf);
|
||||
}
|
||||
|
||||
|
@ -1126,7 +1125,7 @@ S3_Close_internal( void* fd,
|
|||
start_multiplier = ETAG_SIZE; /* one ETag */
|
||||
stride = etag_data_size; /* one rank's-worth of Etag data */
|
||||
}
|
||||
|
||||
|
||||
|
||||
xml = aws_iobuf_new();
|
||||
aws_iobuf_growth_size(xml, 1024 * 8);
|
||||
|
@ -1305,7 +1304,7 @@ S3_Delete( char *testFileName, IOR_param_t * param ) {
|
|||
#if 0
|
||||
// EMC BUG: If file was written with appends, and is deleted,
|
||||
// Then any future recreation will result in an object that can't be read.
|
||||
// this
|
||||
// this
|
||||
AWS4C_CHECK( s3_delete(param->io_buf, testFileName) );
|
||||
#else
|
||||
// just replace with a zero-length object for now
|
||||
|
@ -1334,7 +1333,7 @@ EMC_Delete( char *testFileName, IOR_param_t * param ) {
|
|||
#if 0
|
||||
// EMC BUG: If file was written with appends, and is deleted,
|
||||
// Then any future recreation will result in an object that can't be read.
|
||||
// this
|
||||
// this
|
||||
AWS4C_CHECK( s3_delete(param->io_buf, testFileName) );
|
||||
#else
|
||||
// just replace with a zero-length object for now
|
||||
|
@ -1353,25 +1352,6 @@ EMC_Delete( char *testFileName, IOR_param_t * param ) {
|
|||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Determine API version.
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
S3_SetVersion( IOR_param_t * param ) {
|
||||
if (param->verbose >= VERBOSE_2) {
|
||||
printf("-> S3_SetVersion\n");
|
||||
}
|
||||
|
||||
strcpy( param->apiVersion, param->api );
|
||||
|
||||
if (param->verbose >= VERBOSE_2) {
|
||||
printf("<- S3_SetVersion\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* HTTP HEAD returns meta-data for a "file".
|
||||
*
|
||||
|
|
|
@ -112,13 +112,11 @@ int aiori_posix_stat (const char *path, struct stat *buf, IOR_param_t * param)
|
|||
return stat (path, buf);
|
||||
}
|
||||
|
||||
void aiori_set_version(IOR_param_t * test)
|
||||
char* aiori_get_version()
|
||||
{
|
||||
strcpy(test->apiVersion, test->api);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
const ior_aiori_t *aiori_select (const char *api)
|
||||
{
|
||||
char warn_str[256] = {0};
|
||||
|
|
|
@ -71,7 +71,7 @@ typedef struct ior_aiori {
|
|||
IOR_offset_t, IOR_param_t *);
|
||||
void (*close)(void *, IOR_param_t *);
|
||||
void (*delete)(char *, IOR_param_t *);
|
||||
void (*set_version)(IOR_param_t *);
|
||||
char* (*get_version)();
|
||||
void (*fsync)(void *, IOR_param_t *);
|
||||
IOR_offset_t (*get_file_size)(IOR_param_t *, MPI_Comm, char *);
|
||||
int (*statfs) (const char *, ior_aiori_statfs_t *, IOR_param_t * param);
|
||||
|
@ -99,7 +99,7 @@ int aiori_count (void);
|
|||
const char *aiori_default (void);
|
||||
|
||||
/* some generic POSIX-based backend calls */
|
||||
void aiori_set_version(IOR_param_t * test);
|
||||
char * aiori_get_version();
|
||||
int aiori_posix_statfs (const char *path, ior_aiori_statfs_t *stat_buf, IOR_param_t * param);
|
||||
int aiori_posix_mkdir (const char *path, mode_t mode, IOR_param_t * param);
|
||||
int aiori_posix_rmdir (const char *path, IOR_param_t * param);
|
||||
|
|
|
@ -1,674 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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 General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
@ -1,165 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
|
@ -1,82 +0,0 @@
|
|||
DESCRIPTION
|
||||
-----------
|
||||
This archive contains the source code and supporting documentation for OptList,
|
||||
an ANSI C command line option parser library.
|
||||
|
||||
OptList is released under the GNU LGPL version 3.0.
|
||||
|
||||
The latest revision of this program may be found at:
|
||||
http://michael.dipperstein.com/optlist.html
|
||||
|
||||
FILES
|
||||
-----
|
||||
COPYING - Rules for copying and distributing GNU GPL software
|
||||
COPYING.LESSER - Rules for copying and distributing GNU LGPL software
|
||||
optlist.c - Source code for the Optlist function and supporting
|
||||
function.
|
||||
optlist.h - Header file to be included by code using OptList
|
||||
Makefile - Makefile for this project (assumes gcc compiler and GNU make)
|
||||
README - This file
|
||||
sample.c - A small program demonstrating how to use OptList
|
||||
|
||||
BUILDING
|
||||
--------
|
||||
To build these files with GNU make and gcc:
|
||||
1. Windows users should define the environment variable OS to be Windows or
|
||||
Windows_NT. This is often already done.
|
||||
2. Enter the command "make" from the command line.
|
||||
|
||||
USAGE
|
||||
-----
|
||||
The file sample.c demonstrates the usage of OptList.
|
||||
|
||||
SYNOPSIS
|
||||
typedef struct option_t
|
||||
{
|
||||
char option;
|
||||
char *argument;
|
||||
int argIndex;
|
||||
struct option_t *next;
|
||||
} option_t;
|
||||
|
||||
option_t *GetOptList(int argc, char *const argv[], char *const options);
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
The GetOptList() function is similar to getopt(). Its most notable differences
|
||||
are that it returns a linked list to the command line arguments and their
|
||||
parameters. One call to GetOptList() will return all of the command line
|
||||
options and their arguments. GetOptList() will not modify argc or argv.
|
||||
|
||||
GetOptList()'s parameters "argc" and "argv" are the argument count and array as
|
||||
passed to the main() function on program invocation. An element of argv that
|
||||
starts with "-" is an option element. The character following the "-" is option
|
||||
an character.
|
||||
|
||||
The parameter "options" is a string containing the legitimate option characters.
|
||||
If such a character is followed by a colon, the option requires an argument.
|
||||
(e.g. "a:bc?" a, b ,c, and, ? are all options. a should be followed by an
|
||||
argument.)
|
||||
|
||||
GetOptList() returns a linked list of type option_t. The "*next" field of the
|
||||
element at the end of the list will be set to NULL. The "option" field will
|
||||
contain the option character. A pointer to the following text in the same
|
||||
argv-element, or the text of the following argv-element will be stored in the
|
||||
"arguement" field, otherwise the "arguement" field is set to NULL. The index
|
||||
of the argv-element containing the argument will be stored in the "argIndex".
|
||||
If there is no argument, the field will contain OL_NOINDEX.
|
||||
|
||||
HISTORY
|
||||
-------
|
||||
08/01/07 - Initial release
|
||||
09/13/14 - Added FindFileName function, because I always use it with GetOptList
|
||||
Tighter adherence to Michael Barr's "Top 10 Bug-Killing Coding
|
||||
Standard Rules" (http://www.barrgroup.com/webinars/10rules).
|
||||
|
||||
TODO
|
||||
----
|
||||
- Add support for --option_name
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
|
|
@ -1,290 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Command Line Option Parser
|
||||
*
|
||||
* File : optlist.c
|
||||
* Purpose : Provide getopt style command line option parsing
|
||||
* Author : Michael Dipperstein
|
||||
* Date : August 1, 2007
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* OptList: A command line option parsing library
|
||||
* Copyright (C) 2007, 2014 by
|
||||
* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
|
||||
*
|
||||
* This file is part of the OptList library.
|
||||
*
|
||||
* OptList is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* OptList 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 Lesser
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* INCLUDED FILES
|
||||
***************************************************************************/
|
||||
#include "optlist.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/***************************************************************************
|
||||
* TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* PROTOTYPES
|
||||
***************************************************************************/
|
||||
static option_t *MakeOpt(
|
||||
const char option, char *const argument, const int index);
|
||||
|
||||
static size_t MatchOpt(
|
||||
const char argument, char *const options);
|
||||
|
||||
/***************************************************************************
|
||||
* FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function : GetOptList
|
||||
* Description: This function is similar to the POSIX function getopt. All
|
||||
* options and their corresponding arguments are returned in a
|
||||
* linked list. This function should only be called once per
|
||||
* an option list and it does not modify argv or argc.
|
||||
* Parameters : argc - the number of command line arguments (including the
|
||||
* name of the executable)
|
||||
* argv - pointer to the open binary file to write encoded
|
||||
* output
|
||||
* options - getopt style option list. A NULL terminated
|
||||
* string of single character options. Follow an
|
||||
* option with a colon to indicate that it requires
|
||||
* an argument.
|
||||
* Effects : Creates a link list of command line options and their
|
||||
* arguments.
|
||||
* Returned : option_t type value where the option and arguement fields
|
||||
* contain the next option symbol and its argument (if any).
|
||||
* The argument field will be set to NULL if the option is
|
||||
* specified as having no arguments or no arguments are found.
|
||||
* The option field will be set to PO_NO_OPT if no more
|
||||
* options are found.
|
||||
*
|
||||
* NOTE: The caller is responsible for freeing up the option list when it
|
||||
* is no longer needed.
|
||||
****************************************************************************/
|
||||
option_t *GetOptList(const int argc, char *const argv[], char *const options)
|
||||
{
|
||||
int nextArg;
|
||||
option_t *head, *tail;
|
||||
size_t optIndex;
|
||||
size_t argIndex;
|
||||
|
||||
/* start with first argument and nothing found */
|
||||
nextArg = 1;
|
||||
head = NULL;
|
||||
tail = NULL;
|
||||
|
||||
/* loop through all of the command line arguments */
|
||||
while (nextArg < argc)
|
||||
{
|
||||
argIndex = 1;
|
||||
|
||||
while ((strlen(argv[nextArg]) > argIndex) && ('-' == argv[nextArg][0]))
|
||||
{
|
||||
/* attempt to find a matching option */
|
||||
optIndex = MatchOpt(argv[nextArg][argIndex], options);
|
||||
|
||||
if (options[optIndex] == argv[nextArg][argIndex])
|
||||
{
|
||||
/* we found the matching option */
|
||||
if (NULL == head)
|
||||
{
|
||||
head = MakeOpt(options[optIndex], NULL, OL_NOINDEX);
|
||||
tail = head;
|
||||
}
|
||||
else
|
||||
{
|
||||
tail->next = MakeOpt(options[optIndex], NULL, OL_NOINDEX);
|
||||
tail = tail->next;
|
||||
}
|
||||
|
||||
if (':' == options[optIndex + 1])
|
||||
{
|
||||
/* the option found should have a text arguement */
|
||||
argIndex++;
|
||||
|
||||
if (strlen(argv[nextArg]) > argIndex)
|
||||
{
|
||||
/* no space between argument and option */
|
||||
tail->argument = &(argv[nextArg][argIndex]);
|
||||
tail->argIndex = nextArg;
|
||||
}
|
||||
else if (nextArg < argc)
|
||||
{
|
||||
/* there must be space between the argument option */
|
||||
nextArg++;
|
||||
tail->argument = argv[nextArg];
|
||||
tail->argIndex = nextArg;
|
||||
}
|
||||
|
||||
break; /* done with argv[nextArg] */
|
||||
}
|
||||
}
|
||||
|
||||
argIndex++;
|
||||
}
|
||||
|
||||
nextArg++;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function : MakeOpt
|
||||
* Description: This function uses malloc to allocate space for an option_t
|
||||
* type structure and initailizes the structure with the
|
||||
* values passed as a parameter.
|
||||
* Parameters : option - this option character
|
||||
* argument - pointer string containg the argument for option.
|
||||
* Use NULL for no argument
|
||||
* index - argv[index] contains argument use OL_NOINDEX for
|
||||
* no argument
|
||||
* Effects : A new option_t type variable is created on the heap.
|
||||
* Returned : Pointer to newly created and initialized option_t type
|
||||
* structure. NULL if space for structure can't be allocated.
|
||||
****************************************************************************/
|
||||
static option_t *MakeOpt(
|
||||
const char option, char *const argument, const int index)
|
||||
{
|
||||
option_t *opt;
|
||||
|
||||
opt = malloc(sizeof(option_t));
|
||||
|
||||
if (opt != NULL)
|
||||
{
|
||||
opt->option = option;
|
||||
opt->argument = argument;
|
||||
opt->argIndex = index;
|
||||
opt->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("Failed to Allocate option_t");
|
||||
}
|
||||
|
||||
return opt;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function : FreeOptList
|
||||
* Description: This function will free all the elements in an option_t
|
||||
* type linked list starting from the node passed as a
|
||||
* parameter.
|
||||
* Parameters : list - head of linked list to be freed
|
||||
* Effects : All elements of the linked list pointed to by list will
|
||||
* be freed and list will be set to NULL.
|
||||
* Returned : None
|
||||
****************************************************************************/
|
||||
void FreeOptList(option_t *list)
|
||||
{
|
||||
option_t *head, *next;
|
||||
|
||||
head = list;
|
||||
list = NULL;
|
||||
|
||||
while (head != NULL)
|
||||
{
|
||||
next = head->next;
|
||||
free(head);
|
||||
head = next;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function : MatchOpt
|
||||
* Description: This function searches for an arguement in an option list.
|
||||
* It will return the index to the option matching the
|
||||
* arguement or the index to the NULL if none is found.
|
||||
* Parameters : arguement - character arguement to be matched to an
|
||||
* option in the option list
|
||||
* options - getopt style option list. A NULL terminated
|
||||
* string of single character options. Follow an
|
||||
* option with a colon to indicate that it requires
|
||||
* an argument.
|
||||
* Effects : None
|
||||
* Returned : Index of argument in option list. Index of end of string
|
||||
* if arguement does not appear in the option list.
|
||||
****************************************************************************/
|
||||
static size_t MatchOpt(
|
||||
const char argument, char *const options)
|
||||
{
|
||||
size_t optIndex = 0;
|
||||
|
||||
/* attempt to find a matching option */
|
||||
while ((options[optIndex] != '\0') &&
|
||||
(options[optIndex] != argument))
|
||||
{
|
||||
do
|
||||
{
|
||||
optIndex++;
|
||||
}
|
||||
while ((options[optIndex] != '\0') &&
|
||||
(':' == options[optIndex]));
|
||||
}
|
||||
|
||||
return optIndex;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function : FindFileName
|
||||
* Description: This is function accepts a pointer to the name of a file
|
||||
* along with path information and returns a pointer to the
|
||||
* first character that is not part of the path.
|
||||
* Parameters : fullPath - pointer to an array of characters containing
|
||||
* a file name and possible path modifiers.
|
||||
* Effects : None
|
||||
* Returned : Returns a pointer to the first character after any path
|
||||
* information.
|
||||
****************************************************************************/
|
||||
char *FindFileName(const char *const fullPath)
|
||||
{
|
||||
int i;
|
||||
const char *start; /* start of file name */
|
||||
const char *tmp;
|
||||
const char delim[3] = {'\\', '/', ':'}; /* path deliminators */
|
||||
|
||||
start = fullPath;
|
||||
|
||||
/* find the first character after all file path delimiters */
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
tmp = strrchr(start, delim[i]);
|
||||
|
||||
if (tmp != NULL)
|
||||
{
|
||||
start = tmp + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (char *)start;
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Command Line Option Parser
|
||||
*
|
||||
* File : optlist.h
|
||||
* Purpose : Header for getopt style command line option parsing
|
||||
* Author : Michael Dipperstein
|
||||
* Date : August 1, 2007
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* OptList: A command line option parsing library
|
||||
* Copyright (C) 2007, 20014 by
|
||||
* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
|
||||
*
|
||||
* This file is part of the OptList library.
|
||||
*
|
||||
* OptList is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* OptList 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 Lesser
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef OPTLIST_H
|
||||
#define OPTLIST_H
|
||||
|
||||
/***************************************************************************
|
||||
* INCLUDED FILES
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* MACROS
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* CONSTANTS
|
||||
***************************************************************************/
|
||||
#define OL_NOINDEX -1 /* this option has no arguement */
|
||||
|
||||
/***************************************************************************
|
||||
* TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
typedef struct option_t
|
||||
{
|
||||
char option; /* the current character option character */
|
||||
char *argument; /* pointer to arguments for this option */
|
||||
int argIndex; /* index into argv[] containing the argument */
|
||||
struct option_t *next; /* the next option in the linked list */
|
||||
} option_t;
|
||||
|
||||
/***************************************************************************
|
||||
* PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* returns a linked list of options and arguments similar to getopt() */
|
||||
option_t *GetOptList(int argc, char *const argv[], char *const options);
|
||||
|
||||
/* frees the linked list of option_t returned by GetOptList */
|
||||
void FreeOptList(option_t *list);
|
||||
|
||||
/* return a pointer to file name in a full path. useful for argv[0] */
|
||||
char *FindFileName(const char *const fullPath);
|
||||
|
||||
#endif /* ndef OPTLIST_H */
|
|
@ -1,103 +0,0 @@
|
|||
/***************************************************************************
|
||||
* OptList Usage Sample
|
||||
*
|
||||
* File : sample.c
|
||||
* Purpose : Demonstrates usage of optlist library.
|
||||
* Author : Michael Dipperstein
|
||||
* Date : July 23, 2004
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Sample: A optlist library sample usage program
|
||||
* Copyright (C) 2007, 2014 by
|
||||
* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
|
||||
*
|
||||
* This file is part of the optlist library.
|
||||
*
|
||||
* The optlist library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* The optlist library 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 Lesser
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* INCLUDED FILES
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "optlist.h"
|
||||
|
||||
/***************************************************************************
|
||||
* PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function : main
|
||||
* Description: This is the main function for this program, it calls
|
||||
* optlist to parse the command line input displays the
|
||||
* results of the parsing.
|
||||
* Parameters : argc - number of parameters
|
||||
* argv - parameter list
|
||||
* Effects : parses command line parameters
|
||||
* Returned : EXIT_SUCCESS for success, otherwise EXIT_FAILURE.
|
||||
****************************************************************************/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
option_t *optList, *thisOpt;
|
||||
|
||||
/* get list of command line options and their arguments */
|
||||
optList = NULL;
|
||||
optList = GetOptList(argc, argv, "a:bcd:ef?");
|
||||
|
||||
/* display results of parsing */
|
||||
while (optList != NULL)
|
||||
{
|
||||
thisOpt = optList;
|
||||
optList = optList->next;
|
||||
|
||||
if ('?' == thisOpt->option)
|
||||
{
|
||||
printf("Usage: %s <options>\n\n", FindFileName(argv[0]));
|
||||
printf("options:\n");
|
||||
printf(" -a : option excepting argument.\n");
|
||||
printf(" -b : option without arguments.\n");
|
||||
printf(" -c : option without arguments.\n");
|
||||
printf(" -d : option excepting argument.\n");
|
||||
printf(" -e : option without arguments.\n");
|
||||
printf(" -f : option without arguments.\n");
|
||||
printf(" -? : print out command line options.\n\n");
|
||||
|
||||
FreeOptList(thisOpt); /* free the rest of the list */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
printf("found option %c\n", thisOpt->option);
|
||||
|
||||
if (thisOpt->argument != NULL)
|
||||
{
|
||||
printf("\tfound argument %s", thisOpt->argument);
|
||||
printf(" at index %d\n", thisOpt->argIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tno argument for this option\n");
|
||||
}
|
||||
|
||||
free(thisOpt); /* done with this item, free it */
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -78,7 +78,7 @@ static void PrintKeyValEnd(){
|
|||
}
|
||||
|
||||
static void PrintKeyVal(char * key, char * value){
|
||||
if(value[strlen(value) -1 ] == '\n'){
|
||||
if(value[0] != 0 && value[strlen(value) -1 ] == '\n'){
|
||||
// remove \n
|
||||
value[strlen(value) -1 ] = 0;
|
||||
}
|
||||
|
@ -352,7 +352,6 @@ void ShowTestStart(IOR_param_t *test)
|
|||
PrintKeyValInt("useExistingTestFile", test->useExistingTestFile);
|
||||
PrintKeyValInt("showHints", test->showHints);
|
||||
PrintKeyValInt("uniqueDir", test->uniqueDir);
|
||||
PrintKeyValInt("showHelp", test->showHelp);
|
||||
PrintKeyValInt("individualDataSets", test->individualDataSets);
|
||||
PrintKeyValInt("singleXferAttempt", test->singleXferAttempt);
|
||||
PrintKeyValInt("readFile", test->readFile);
|
||||
|
@ -407,7 +406,7 @@ void ShowTestEnd(IOR_test_t *tptr){
|
|||
*/
|
||||
void ShowSetup(IOR_param_t *params)
|
||||
{
|
||||
if (strcmp(params->debug, "") != 0) {
|
||||
if (params->debug) {
|
||||
fprintf(out_logfile, "\n*** DEBUG MODE ***\n");
|
||||
fprintf(out_logfile, "*** %s ***\n\n", params->debug);
|
||||
}
|
||||
|
|
171
src/ior.c
171
src/ior.c
|
@ -43,10 +43,9 @@ static int totalErrorCount;
|
|||
static const ior_aiori_t *backend;
|
||||
|
||||
static void DestroyTests(IOR_test_t *tests_head);
|
||||
static void DisplayUsage(char **);
|
||||
static char *PrependDir(IOR_param_t *, char *);
|
||||
static char **ParseFileName(char *, int *);
|
||||
static IOR_test_t *SetupTests(int, char **);
|
||||
static void InitTests(IOR_test_t * , MPI_Comm);
|
||||
static void TestIoSys(IOR_test_t *);
|
||||
static void ValidateTests(IOR_param_t *);
|
||||
static IOR_offset_t WriteOrRead(IOR_param_t * test, IOR_results_t * results, void *fd, int access, IOR_io_buffers* ioBuffers);
|
||||
|
@ -70,14 +69,9 @@ IOR_test_t * ior_run(int argc, char **argv, MPI_Comm world_com, FILE * world_out
|
|||
}
|
||||
|
||||
/* setup tests, and validate parameters */
|
||||
tests_head = SetupTests(argc, argv);
|
||||
tests_head = ParseCommandLine(argc, argv);
|
||||
InitTests(tests_head, world_com);
|
||||
verbose = tests_head->params.verbose;
|
||||
tests_head->params.testComm = world_com;
|
||||
|
||||
/* check for commandline 'help' request */
|
||||
if (rank == 0 && tests_head->params.showHelp == TRUE) {
|
||||
DisplayUsage(argv);
|
||||
}
|
||||
|
||||
PrintHeader(argc, argv);
|
||||
|
||||
|
@ -85,7 +79,6 @@ IOR_test_t * ior_run(int argc, char **argv, MPI_Comm world_com, FILE * world_out
|
|||
for (tptr = tests_head; tptr != NULL; tptr = tptr->next) {
|
||||
totalErrorCount = 0;
|
||||
verbose = tptr->params.verbose;
|
||||
tptr->params.testComm = world_com;
|
||||
if (rank == 0 && verbose >= VERBOSE_0) {
|
||||
ShowTestStart(&tptr->params);
|
||||
}
|
||||
|
@ -114,15 +107,8 @@ int ior_main(int argc, char **argv)
|
|||
|
||||
/*
|
||||
* check -h option from commandline without starting MPI;
|
||||
* if the help option is requested in a script file (showHelp=TRUE),
|
||||
* the help output will be displayed in the MPI job
|
||||
*/
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-h") == 0) {
|
||||
DisplayUsage(argv);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
tests_head = ParseCommandLine(argc, argv);
|
||||
|
||||
#ifdef USE_S3_AIORI
|
||||
/* This is supposed to be done before *any* threads are created.
|
||||
|
@ -152,18 +138,8 @@ int ior_main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* setup tests, and validate parameters */
|
||||
tests_head = SetupTests(argc, argv);
|
||||
InitTests(tests_head, mpi_comm_world);
|
||||
verbose = tests_head->params.verbose;
|
||||
tests_head->params.testComm = mpi_comm_world;
|
||||
|
||||
/* check for commandline 'help' request */
|
||||
if (tests_head->params.showHelp == TRUE) {
|
||||
if( rank == 0 ){
|
||||
DisplayUsage(argv);
|
||||
}
|
||||
MPI_Finalize();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
PrintHeader(argc, argv);
|
||||
|
||||
|
@ -223,9 +199,12 @@ void init_IOR_Param_t(IOR_param_t * p)
|
|||
p->mode = IOR_IRUSR | IOR_IWUSR | IOR_IRGRP | IOR_IWGRP;
|
||||
p->openFlags = IOR_RDWR | IOR_CREAT;
|
||||
|
||||
strncpy(p->api, default_aiori, MAX_STR);
|
||||
strncpy(p->platform, "HOST(OSTYPE)", MAX_STR);
|
||||
strncpy(p->testFileName, "testFile", MAX_PATHLEN);
|
||||
p->api = strdup(default_aiori);
|
||||
p->platform = strdup("HOST(OSTYPE)");
|
||||
p->testFileName = strdup("testFile");
|
||||
|
||||
p->writeFile = p->readFile = FALSE;
|
||||
p->checkWrite = p->checkRead = FALSE;
|
||||
|
||||
p->nodes = 1;
|
||||
p->tasksPerNode = 1;
|
||||
|
@ -244,8 +223,8 @@ void init_IOR_Param_t(IOR_param_t * p)
|
|||
|
||||
hdfs_user = getenv("USER");
|
||||
if (!hdfs_user)
|
||||
hdfs_user = "";
|
||||
strncpy(p->hdfs_user, hdfs_user, MAX_STR);
|
||||
hdfs_user = "";
|
||||
p->hdfs_user = strdup(hdfs_user);
|
||||
p->hdfs_name_node = "default";
|
||||
p->hdfs_name_node_port = 0; /* ??? */
|
||||
p->hdfs_fs = NULL;
|
||||
|
@ -557,7 +536,7 @@ static void aligned_buffer_free(void *buf)
|
|||
free(*(void **)((char *)buf - sizeof(char *)));
|
||||
}
|
||||
|
||||
void AllocResults(IOR_test_t *test)
|
||||
static void AllocResults(IOR_test_t *test)
|
||||
{
|
||||
int reps;
|
||||
if (test->results != NULL)
|
||||
|
@ -619,12 +598,12 @@ IOR_test_t *CreateTest(IOR_param_t *init_params, int test_num)
|
|||
if (newTest == NULL)
|
||||
ERR("malloc() of IOR_test_t failed");
|
||||
newTest->params = *init_params;
|
||||
GetPlatformName(newTest->params.platform);
|
||||
newTest->params.nodes = init_params->numTasks / tasksPerNode;
|
||||
newTest->params.tasksPerNode = tasksPerNode;
|
||||
newTest->params.platform = GetPlatformName();
|
||||
newTest->params.id = test_num;
|
||||
newTest->next = NULL;
|
||||
newTest->results = NULL;
|
||||
|
||||
AllocResults(newTest);
|
||||
return newTest;
|
||||
}
|
||||
|
||||
|
@ -644,82 +623,6 @@ static void DestroyTests(IOR_test_t *tests_head)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Display usage of script file.
|
||||
*/
|
||||
static void DisplayUsage(char **argv)
|
||||
{
|
||||
char *opts[] = {
|
||||
"OPTIONS:",
|
||||
" -a S api -- API for I/O [POSIX|MMAP|MPIIO|HDF5|HDFS|S3|S3_EMC|NCMPI]",
|
||||
" -A N refNum -- user supplied reference number to include in the summary",
|
||||
" -b N blockSize -- contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)",
|
||||
" -B useO_DIRECT -- uses O_DIRECT for POSIX, bypassing I/O buffers",
|
||||
" -c collective -- collective I/O",
|
||||
" -C reorderTasks -- changes task ordering to n+1 ordering for readback",
|
||||
" -d N interTestDelay -- delay between reps in seconds",
|
||||
" -D N deadlineForStonewalling -- seconds before stopping write or read phase",
|
||||
" -O stoneWallingWearOut=1 -- once the stonewalling timout is over, all process finish to access the amount of data",
|
||||
" -O stoneWallingWearOutIterations=N -- stop after processing this number of iterations, needed for reading data back written with stoneWallingWearOut",
|
||||
" -O stoneWallingStatusFile=FILE -- this file keeps the number of iterations from stonewalling during write and allows to use them for read",
|
||||
" -e fsync -- perform fsync/msync upon POSIX/MMAP write close",
|
||||
" -E useExistingTestFile -- do not remove test file before write access",
|
||||
" -f S scriptFile -- test script name",
|
||||
" -F filePerProc -- file-per-process",
|
||||
" -g intraTestBarriers -- use barriers between open, write/read, and close",
|
||||
" -G N setTimeStampSignature -- set value for time stamp signature/random seed",
|
||||
" -h showHelp -- displays options and help",
|
||||
" -H showHints -- show hints",
|
||||
" -i N repetitions -- number of repetitions of test",
|
||||
" -I individualDataSets -- datasets not shared by all procs [not working]",
|
||||
" -j N outlierThreshold -- warn on outlier N seconds from mean",
|
||||
" -J N setAlignment -- HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g)",
|
||||
" -k keepFile -- don't remove the test file(s) on program exit",
|
||||
" -K keepFileWithError -- keep error-filled file(s) after data-checking",
|
||||
" -l datapacket type-- type of packet that will be created [offset|incompressible|timestamp|o|i|t]",
|
||||
" -m multiFile -- use number of reps (-i) for multiple file count",
|
||||
" -M N memoryPerNode -- hog memory on the node (e.g.: 2g, 75%)",
|
||||
" -n noFill -- no fill in HDF5 file creation",
|
||||
" -N N numTasks -- number of tasks that should participate in the test",
|
||||
" -o S testFile -- full name for test",
|
||||
" -O S string of IOR directives (e.g. -O checkRead=1,lustreStripeCount=32)",
|
||||
" -p preallocate -- preallocate file size",
|
||||
" -P useSharedFilePointer -- use shared file pointer [not working]",
|
||||
" -q quitOnError -- during file error-checking, abort on error",
|
||||
" -Q N taskPerNodeOffset for read tests use with -C & -Z options (-C constant N, -Z at least N)",
|
||||
" -r readFile -- read existing file",
|
||||
" -R checkRead -- verify that the output of read matches the expected signature (used with -G)",
|
||||
" -s N segmentCount -- number of segments",
|
||||
" -S useStridedDatatype -- put strided access into datatype [not working]",
|
||||
" -t N transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)",
|
||||
" -T N maxTimeDuration -- max time in minutes executing repeated test; it aborts only between iterations and not within a test!",
|
||||
" -u uniqueDir -- use unique directory name for each file-per-process",
|
||||
" -U S hintsFileName -- full name for hints file",
|
||||
" -v verbose -- output information (repeating flag increases level)",
|
||||
" -V useFileView -- use MPI_File_set_view",
|
||||
" -w writeFile -- write file",
|
||||
" -W checkWrite -- check read after write",
|
||||
" -x singleXferAttempt -- do not retry transfer if incomplete",
|
||||
" -X N reorderTasksRandomSeed -- random seed for -Z option",
|
||||
" -Y fsyncPerWrite -- perform fsync/msync after each POSIX/MMAP write",
|
||||
" -z randomOffset -- access is to random, not sequential, offsets within a file",
|
||||
" -Z reorderTasksRandom -- changes task ordering to random ordering for readback",
|
||||
" -O summaryFile=FILE -- store result data into this file",
|
||||
" -O summaryFormat=[default,JSON,CSV] -- use the format for outputing the summary",
|
||||
" ",
|
||||
" NOTE: S is a string, N is an integer number.",
|
||||
" ",
|
||||
""
|
||||
};
|
||||
int i = 0;
|
||||
|
||||
fprintf(out_logfile, "Usage: %s [OPTIONS]\n\n", *argv);
|
||||
for (i = 0; strlen(opts[i]) > 0; i++)
|
||||
fprintf(out_logfile, "%s\n", opts[i]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Distribute IOR_HINTs to all tasks' environments.
|
||||
*/
|
||||
|
@ -823,9 +726,10 @@ FillBuffer(void *buffer,
|
|||
/*
|
||||
* Return string describing machine name and type.
|
||||
*/
|
||||
void GetPlatformName(char *platformName)
|
||||
char * GetPlatformName()
|
||||
{
|
||||
char nodeName[MAX_STR], *p, *start, sysName[MAX_STR];
|
||||
char platformName[MAX_STR];
|
||||
struct utsname name;
|
||||
|
||||
if (uname(&name) != 0) {
|
||||
|
@ -858,6 +762,7 @@ void GetPlatformName(char *platformName)
|
|||
}
|
||||
|
||||
sprintf(platformName, "%s(%s)", nodeName, sysName);
|
||||
return strdup(platformName);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1097,14 +1002,16 @@ static void RemoveFile(char *testFileName, int filePerProc, IOR_param_t * test)
|
|||
* Setup tests by parsing commandline and creating test script.
|
||||
* Perform a sanity-check on the configured parameters.
|
||||
*/
|
||||
static IOR_test_t *SetupTests(int argc, char **argv)
|
||||
static void InitTests(IOR_test_t *tests, MPI_Comm com)
|
||||
{
|
||||
IOR_test_t *tests, *testsHead;
|
||||
IOR_test_t *testsHead = tests;
|
||||
int size;
|
||||
|
||||
MPI_CHECK(MPI_Comm_size(com, & size), "MPI_Comm_size() error");
|
||||
|
||||
/* count the tasks per node */
|
||||
tasksPerNode = CountTasksPerNode(mpi_comm_world);
|
||||
tasksPerNode = CountTasksPerNode(com);
|
||||
|
||||
testsHead = tests = ParseCommandLine(argc, argv);
|
||||
/*
|
||||
* Since there is no guarantee that anyone other than
|
||||
* task 0 has the environment settings for the hints, pass
|
||||
|
@ -1114,6 +1021,16 @@ static IOR_test_t *SetupTests(int argc, char **argv)
|
|||
|
||||
/* check validity of tests and create test queue */
|
||||
while (tests != NULL) {
|
||||
IOR_param_t *params = & tests->params;
|
||||
params->testComm = com;
|
||||
params->nodes = params->numTasks / tasksPerNode;
|
||||
params->tasksPerNode = tasksPerNode;
|
||||
if (params->numTasks == 0) {
|
||||
params->numTasks = size;
|
||||
}
|
||||
params->expectedAggFileSize =
|
||||
params->blockSize * params->segmentCount * params->numTasks;
|
||||
|
||||
ValidateTests(&tests->params);
|
||||
tests = tests->next;
|
||||
}
|
||||
|
@ -1122,8 +1039,6 @@ static IOR_test_t *SetupTests(int argc, char **argv)
|
|||
|
||||
/* seed random number generator */
|
||||
SeedRandGen(mpi_comm_world);
|
||||
|
||||
return (testsHead);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1468,8 +1383,7 @@ static void TestIoSys(IOR_test_t *test)
|
|||
}
|
||||
if (params->reorderTasks) {
|
||||
/* move two nodes away from writing node */
|
||||
rankOffset =
|
||||
(2 * params->tasksPerNode) % params->numTasks;
|
||||
rankOffset = (2 * params->tasksPerNode) % params->numTasks;
|
||||
}
|
||||
|
||||
// update the check buffer
|
||||
|
@ -1497,9 +1411,8 @@ static void TestIoSys(IOR_test_t *test)
|
|||
/* Constant process offset reading */
|
||||
if (params->reorderTasks) {
|
||||
/* move taskPerNodeOffset nodes[1==default] away from writing node */
|
||||
rankOffset =
|
||||
(params->taskPerNodeOffset *
|
||||
params->tasksPerNode) % params->numTasks;
|
||||
rankOffset = (params->taskPerNodeOffset *
|
||||
params->tasksPerNode) % params->numTasks;
|
||||
}
|
||||
/* random process offset reading */
|
||||
if (params->reorderTasksRandom) {
|
||||
|
@ -1626,10 +1539,6 @@ static void ValidateTests(IOR_param_t * test)
|
|||
IOR_param_t defaults;
|
||||
init_IOR_Param_t(&defaults);
|
||||
|
||||
/* get the version of the tests */
|
||||
AioriBind(test->api, test);
|
||||
backend->set_version(test);
|
||||
|
||||
if (test->repetitions <= 0)
|
||||
WARN_RESET("too few test repetitions",
|
||||
test, &defaults, repetitions);
|
||||
|
@ -2005,7 +1914,7 @@ static IOR_offset_t WriteOrRead(IOR_param_t * test, IOR_results_t * results, voi
|
|||
&& ((GetTimeStamp() - startForStonewall)
|
||||
> test->deadlineForStonewalling));
|
||||
|
||||
if(access == READ && test->stoneWallingStatusFile[0]){
|
||||
if(access == READ && test->stoneWallingStatusFile){
|
||||
test->stoneWallingWearOutIterations = ReadStoneWallingIterations(test->stoneWallingStatusFile);
|
||||
if(test->stoneWallingWearOutIterations == -1){
|
||||
ERR("Could not read back the stonewalling status from the file!");
|
||||
|
|
28
src/ior.h
28
src/ior.h
|
@ -87,17 +87,18 @@ typedef struct IO_BUFFERS
|
|||
|
||||
typedef struct
|
||||
{
|
||||
char debug[MAX_STR]; /* debug info string */
|
||||
const void * backend;
|
||||
char * debug; /* debug info string */
|
||||
unsigned int mode; /* file permissions */
|
||||
unsigned int openFlags; /* open flags (see also <open>) */
|
||||
int referenceNumber; /* user supplied reference number */
|
||||
char api[MAX_STR]; /* API for I/O */
|
||||
char apiVersion[MAX_STR]; /* API version */
|
||||
char platform[MAX_STR]; /* platform type */
|
||||
char testFileName[MAXPATHLEN]; /* full name for test */
|
||||
char testFileName_fppReadCheck[MAXPATHLEN];/* filename for fpp read check */
|
||||
char hintsFileName[MAXPATHLEN]; /* full name for hints file */
|
||||
char options[MAXPATHLEN]; /* options string */
|
||||
char * api; /* API for I/O */
|
||||
char * apiVersion; /* API version */
|
||||
char * platform; /* platform type */
|
||||
char * testFileName; /* full name for test */
|
||||
char * testFileName_fppReadCheck;/* filename for fpp read check */
|
||||
char * hintsFileName; /* full name for hints file */
|
||||
char * options; /* options string */
|
||||
int numTasks; /* number of tasks for test */
|
||||
int nodes; /* number of nodes for test */
|
||||
int tasksPerNode; /* number of tasks per node */
|
||||
|
@ -131,7 +132,6 @@ typedef struct
|
|||
int useStridedDatatype; /* put strided access into datatype */
|
||||
int useO_DIRECT; /* use O_DIRECT, bypassing I/O buffers */
|
||||
int showHints; /* show hints */
|
||||
int showHelp; /* show options and help */
|
||||
int summary_every_test; /* flag to print summary every test, not just at end */
|
||||
int uniqueDir; /* use unique directory for each fpp */
|
||||
int useExistingTestFile; /* do not delete test file before access */
|
||||
|
@ -139,7 +139,7 @@ typedef struct
|
|||
int deadlineForStonewalling; /* max time in seconds to run any test phase */
|
||||
int stoneWallingWearOut; /* wear out the stonewalling, once the timout is over, each process has to write the same amount */
|
||||
uint64_t stoneWallingWearOutIterations; /* the number of iterations for the stonewallingWearOut, needed for readBack */
|
||||
char stoneWallingStatusFile[MAXPATHLEN];
|
||||
char * stoneWallingStatusFile;
|
||||
|
||||
int maxTimeDuration; /* max time in minutes to run each test */
|
||||
int outlierThreshold; /* warn on outlier N seconds from mean */
|
||||
|
@ -173,7 +173,7 @@ typedef struct
|
|||
IOR_offset_t setAlignment; /* alignment in bytes */
|
||||
|
||||
/* HDFS variables */
|
||||
char hdfs_user[MAX_STR]; /* copied from ENV, for now */
|
||||
char * hdfs_user; /* copied from ENV, for now */
|
||||
const char* hdfs_name_node;
|
||||
tPort hdfs_name_node_port; /* (uint16_t) */
|
||||
hdfsFS hdfs_fs; /* file-system handle */
|
||||
|
@ -190,8 +190,7 @@ typedef struct
|
|||
IOBuf* io_buf; /* aws4c places parsed header values here */
|
||||
IOBuf* etags; /* accumulate ETags for N:1 parts */
|
||||
size_t part_number; /* multi-part upload increment (PER-RANK!) */
|
||||
# define MAX_UPLOAD_ID_SIZE 256 /* seems to be 32, actually */
|
||||
char UploadId[MAX_UPLOAD_ID_SIZE +1]; /* key for multi-part-uploads */
|
||||
char* UploadId; /* key for multi-part-uploads */
|
||||
|
||||
/* RADOS variables */
|
||||
rados_t rados_cluster; /* RADOS cluster handle */
|
||||
|
@ -245,8 +244,7 @@ typedef struct IOR_test_t {
|
|||
|
||||
|
||||
IOR_test_t *CreateTest(IOR_param_t *init_params, int test_num);
|
||||
void AllocResults(IOR_test_t *test);
|
||||
void GetPlatformName(char *);
|
||||
char * GetPlatformName();
|
||||
void init_IOR_Param_t(IOR_param_t *p);
|
||||
|
||||
/*
|
||||
|
|
|
@ -2154,7 +2154,7 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
|
|||
int printhelp = 0;
|
||||
int parsed_options = option_parse(argc, argv, options, & printhelp);
|
||||
|
||||
backend = aiori_select (backend_name);
|
||||
backend = aiori_select(backend_name);
|
||||
if (NULL == backend) {
|
||||
FAIL("Could not find suitable backend to use");
|
||||
}
|
||||
|
@ -2164,7 +2164,7 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
|
|||
}
|
||||
|
||||
if(printhelp != 0){
|
||||
printf("\nSynopsis: %s ", argv[0]);
|
||||
printf("Usage: %s ", argv[0]);
|
||||
|
||||
option_print_help(options, 0);
|
||||
|
||||
|
|
77
src/option.c
77
src/option.c
|
@ -6,6 +6,45 @@
|
|||
|
||||
#include <option.h>
|
||||
|
||||
/*
|
||||
* Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes.
|
||||
*/
|
||||
int64_t string_to_bytes(char *size_str)
|
||||
{
|
||||
int64_t size = 0;
|
||||
char range;
|
||||
int rc;
|
||||
|
||||
rc = sscanf(size_str, " %lld %c ", (long long*) & size, &range);
|
||||
if (rc == 2) {
|
||||
switch ((int)range) {
|
||||
case 'k':
|
||||
case 'K':
|
||||
size <<= 10;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
size <<= 20;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
size <<= 30;
|
||||
break;
|
||||
case 't':
|
||||
case 'T':
|
||||
size <<= 40;
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
size <<= 50;
|
||||
break;
|
||||
}
|
||||
} else if (rc == 0) {
|
||||
size = -1;
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initial revision by JK
|
||||
*/
|
||||
|
@ -16,6 +55,10 @@ static int print_value(option_help * o){
|
|||
assert(o->variable != NULL);
|
||||
|
||||
switch(o->type){
|
||||
case('p'):{
|
||||
pos += printf("=STRING");
|
||||
break;
|
||||
}
|
||||
case('F'):{
|
||||
pos += printf("=%.14f ", *(double*) o->variable);
|
||||
break;
|
||||
|
@ -59,12 +102,12 @@ static void print_help_section(option_help * args, option_value_type type, char
|
|||
first = 1;
|
||||
option_help * o;
|
||||
for(o = args; o->shortVar != 0 || o->longVar != 0 || o->help != NULL ; o++){
|
||||
if( o->shortVar == 0 && o->longVar == 0 && o->help != NULL){
|
||||
printf("%-15s %s\n", "", o->help);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (o->arg == type){
|
||||
if( o->shortVar == 0 && o->longVar == 0 && o->help != NULL){
|
||||
printf("%s\n", o->help);
|
||||
continue;
|
||||
}
|
||||
if (first){
|
||||
printf("\n%s\n", name);
|
||||
first = 0;
|
||||
|
@ -235,13 +278,13 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){
|
|||
|
||||
// try to find matching option help
|
||||
for(option_help * o = args; o->shortVar != 0 || o->longVar != 0 || o->help != NULL ; o++ ){
|
||||
if ( (strlen(txt) == 2 && txt[0] == '-' && o->shortVar == txt[1]) || (strlen(txt) > 2 && txt[0] == '-' && txt[1] == '-' && o->longVar != NULL && strcmp(txt + 2, o->longVar) == 0)){
|
||||
foundOption = 1;
|
||||
if( o->shortVar == 0 && o->longVar == 0 ){
|
||||
// section
|
||||
continue;
|
||||
}
|
||||
|
||||
if( o->shortVar == 0 && o->longVar == 0 && o->help != NULL){
|
||||
// section
|
||||
continue;
|
||||
}
|
||||
if ( (txt[0] == '-' && o->shortVar == txt[1]) || (strlen(txt) > 2 && txt[0] == '-' && txt[1] == '-' && o->longVar != NULL && strcmp(txt + 2, o->longVar) == 0)){
|
||||
foundOption = 1;
|
||||
|
||||
// now process the option.
|
||||
switch(o->arg){
|
||||
|
@ -254,9 +297,13 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){
|
|||
case (OPTION_REQUIRED_ARGUMENT):{
|
||||
// check if next is an argument
|
||||
if(arg == NULL){
|
||||
// simply take the next value as argument
|
||||
i++;
|
||||
arg = argv[i];
|
||||
if(o->shortVar == txt[1] && txt[2] != 0){
|
||||
arg = & txt[2];
|
||||
}else{
|
||||
// simply take the next value as argument
|
||||
i++;
|
||||
arg = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
switch(o->type){
|
||||
|
@ -269,7 +316,7 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){
|
|||
break;
|
||||
}
|
||||
case('d'):{
|
||||
*(int*) o->variable = atoi(arg);
|
||||
*(int*) o->variable = string_to_bytes(arg);
|
||||
break;
|
||||
}
|
||||
case('H'):
|
||||
|
@ -285,7 +332,7 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){
|
|||
break;
|
||||
}
|
||||
case('l'):{
|
||||
*(long long*) o->variable = atoll(arg);
|
||||
*(long long*) o->variable = string_to_bytes(arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#ifndef IOR_OPTION_H
|
||||
#define IOR_OPTION_H
|
||||
#ifndef _IOR_OPTION_H
|
||||
#define _IOR_OPTION_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Initial revision by JK
|
||||
|
@ -23,6 +25,7 @@ typedef struct{
|
|||
|
||||
#define LAST_OPTION {0, 0, 0, (option_value_type) 0, 0, NULL}
|
||||
|
||||
int64_t string_to_bytes(char *size_str);
|
||||
void option_print_help(option_help * args, int is_plugin);
|
||||
void option_print_current(option_help * args);
|
||||
|
||||
|
|
|
@ -22,54 +22,17 @@
|
|||
#include <string.h>
|
||||
|
||||
|
||||
#include <getopt/optlist.h>
|
||||
#include "utilities.h"
|
||||
#include "ior.h"
|
||||
#include "aiori.h"
|
||||
#include "parse_options.h"
|
||||
#include "option.h"
|
||||
#include "aiori.h"
|
||||
|
||||
#define ISPOWEROFTWO(x) ((x != 0) && !(x & (x - 1)))
|
||||
|
||||
IOR_param_t initialTestParams;
|
||||
|
||||
/*
|
||||
* Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes.
|
||||
*/
|
||||
static IOR_offset_t StringToBytes(char *size_str)
|
||||
{
|
||||
IOR_offset_t size = 0;
|
||||
char range;
|
||||
int rc;
|
||||
|
||||
rc = sscanf(size_str, " %lld %c ", &size, &range);
|
||||
if (rc == 2) {
|
||||
switch ((int)range) {
|
||||
case 'k':
|
||||
case 'K':
|
||||
size <<= 10;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
size <<= 20;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
size <<= 30;
|
||||
break;
|
||||
case 't':
|
||||
case 'T':
|
||||
size <<= 40;
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
size <<= 50;
|
||||
break;
|
||||
}
|
||||
} else if (rc == 0) {
|
||||
size = -1;
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
|
||||
static size_t NodeMemoryStringToBytes(char *size_str)
|
||||
{
|
||||
|
@ -81,7 +44,7 @@ static size_t NodeMemoryStringToBytes(char *size_str)
|
|||
|
||||
rc = sscanf(size_str, " %d %% ", &percent);
|
||||
if (rc == 0)
|
||||
return (size_t)StringToBytes(size_str);
|
||||
return (size_t) string_to_bytes(size_str);
|
||||
if (percent > 100 || percent < 0)
|
||||
ERR("percentage must be between 0 and 100");
|
||||
|
||||
|
@ -98,11 +61,6 @@ static size_t NodeMemoryStringToBytes(char *size_str)
|
|||
return mem / 100 * percent;
|
||||
}
|
||||
|
||||
static void RecalculateExpectedFileSize(IOR_param_t *params)
|
||||
{
|
||||
params->expectedAggFileSize =
|
||||
params->blockSize * params->segmentCount * params->numTasks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check and correct all settings of each test in queue for correctness.
|
||||
|
@ -143,13 +101,6 @@ static void CheckRunSettings(IOR_test_t *tests)
|
|||
params->openFlags |= IOR_WRONLY;
|
||||
}
|
||||
|
||||
/* If numTasks set to 0, use all tasks */
|
||||
if (params->numTasks == 0) {
|
||||
MPI_CHECK(MPI_Comm_size(mpi_comm_world,
|
||||
¶ms->numTasks),
|
||||
"MPI_Comm_size() error");
|
||||
RecalculateExpectedFileSize(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,15 +198,13 @@ void DecodeDirective(char *line, IOR_param_t *params)
|
|||
} else if (strcasecmp(option, "quitonerror") == 0) {
|
||||
params->quitOnError = atoi(value);
|
||||
} else if (strcasecmp(option, "segmentcount") == 0) {
|
||||
params->segmentCount = StringToBytes(value);
|
||||
RecalculateExpectedFileSize(params);
|
||||
params->segmentCount = string_to_bytes(value);
|
||||
} else if (strcasecmp(option, "blocksize") == 0) {
|
||||
params->blockSize = StringToBytes(value);
|
||||
RecalculateExpectedFileSize(params);
|
||||
params->blockSize = string_to_bytes(value);
|
||||
} else if (strcasecmp(option, "transfersize") == 0) {
|
||||
params->transferSize = StringToBytes(value);
|
||||
params->transferSize = string_to_bytes(value);
|
||||
} else if (strcasecmp(option, "setalignment") == 0) {
|
||||
params->setAlignment = StringToBytes(value);
|
||||
params->setAlignment = string_to_bytes(value);
|
||||
} else if (strcasecmp(option, "singlexferattempt") == 0) {
|
||||
params->singleXferAttempt = atoi(value);
|
||||
} else if (strcasecmp(option, "individualdatasets") == 0) {
|
||||
|
@ -284,8 +233,6 @@ void DecodeDirective(char *line, IOR_param_t *params)
|
|||
params->useStridedDatatype = atoi(value);
|
||||
} else if (strcasecmp(option, "showhints") == 0) {
|
||||
params->showHints = atoi(value);
|
||||
} else if (strcasecmp(option, "showhelp") == 0) {
|
||||
params->showHelp = atoi(value);
|
||||
} else if (strcasecmp(option, "uniqueDir") == 0) {
|
||||
params->uniqueDir = atoi(value);
|
||||
} else if (strcasecmp(option, "useexistingtestfile") == 0) {
|
||||
|
@ -297,7 +244,7 @@ void DecodeDirective(char *line, IOR_param_t *params)
|
|||
} else if (strcasecmp(option, "randomoffset") == 0) {
|
||||
params->randomOffset = atoi(value);
|
||||
} else if (strcasecmp(option, "memoryPerTask") == 0) {
|
||||
params->memoryPerTask = StringToBytes(value);
|
||||
params->memoryPerTask = string_to_bytes(value);
|
||||
params->memoryPerNode = 0;
|
||||
} else if (strcasecmp(option, "memoryPerNode") == 0) {
|
||||
params->memoryPerNode = NodeMemoryStringToBytes(value);
|
||||
|
@ -312,7 +259,7 @@ void DecodeDirective(char *line, IOR_param_t *params)
|
|||
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
||||
ERR("ior was not compiled with Lustre support");
|
||||
#endif
|
||||
params->lustre_stripe_size = StringToBytes(value);
|
||||
params->lustre_stripe_size = string_to_bytes(value);
|
||||
params->lustre_set_striping = 1;
|
||||
} else if (strcasecmp(option, "lustrestartost") == 0) {
|
||||
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
||||
|
@ -346,12 +293,11 @@ void DecodeDirective(char *line, IOR_param_t *params)
|
|||
#ifndef HAVE_BEEGFS_BEEGFS_H
|
||||
ERR("ior was not compiled with BeeGFS support");
|
||||
#endif
|
||||
params->beegfs_chunkSize = StringToBytes(value);
|
||||
params->beegfs_chunkSize = string_to_bytes(value);
|
||||
if (!ISPOWEROFTWO(params->beegfs_chunkSize) || params->beegfs_chunkSize < (1<<16))
|
||||
ERR("beegfsChunkSize must be a power of two and >64k");
|
||||
} else if (strcasecmp(option, "numtasks") == 0) {
|
||||
params->numTasks = atoi(value);
|
||||
RecalculateExpectedFileSize(params);
|
||||
} else if (strcasecmp(option, "summaryalways") == 0) {
|
||||
params->summary_every_test = atoi(value);
|
||||
} else {
|
||||
|
@ -377,7 +323,6 @@ void ParseLine(char *line, IOR_param_t * test)
|
|||
DecodeDirective(start, test);
|
||||
start = end + 1;
|
||||
} while (end != NULL);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -445,7 +390,6 @@ IOR_test_t *ReadConfigScript(char *scriptName)
|
|||
if (sscanf(linebuf, " #%s", empty) == 1)
|
||||
continue;
|
||||
if (contains_only(linebuf, "ior stop")) {
|
||||
AllocResults(tail);
|
||||
break;
|
||||
} else if (contains_only(linebuf, "run")) {
|
||||
if (runflag) {
|
||||
|
@ -454,7 +398,6 @@ IOR_test_t *ReadConfigScript(char *scriptName)
|
|||
tail->next = CreateTest(&tail->params, test_num++);
|
||||
tail = tail->next;
|
||||
}
|
||||
AllocResults(tail);
|
||||
runflag = 1;
|
||||
} else if (runflag) {
|
||||
/* If this directive was preceded by a "run" line, then
|
||||
|
@ -475,214 +418,148 @@ IOR_test_t *ReadConfigScript(char *scriptName)
|
|||
return head;
|
||||
}
|
||||
|
||||
|
||||
static IOR_param_t * parameters;
|
||||
|
||||
static void decodeDirectiveWrapper(char *line){
|
||||
DecodeDirective(line, parameters);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse Commandline.
|
||||
*/
|
||||
IOR_test_t *ParseCommandLine(int argc, char **argv)
|
||||
{
|
||||
char * const opts =
|
||||
"a:A:b:BcCd:D:eEf:FgG:hHi:Ij:J:kKl:mM:nN:o:O:pPqQ:rRs:St:T:uU:vVwWxX:YzZ";
|
||||
char * testscripts = NULL;
|
||||
int toggleG = FALSE;
|
||||
char * buffer_type = "";
|
||||
char * memoryPerNode = NULL;
|
||||
init_IOR_Param_t(& initialTestParams);
|
||||
parameters = & initialTestParams;
|
||||
|
||||
option_help options [] = {
|
||||
{'a', NULL, "API for I/O [POSIX|MPIIO|HDF5|HDFS|S3|S3_EMC|NCMPI]", OPTION_OPTIONAL_ARGUMENT, 's', & initialTestParams.api},
|
||||
{'A', NULL, "refNum -- user supplied reference number to include in the summary", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.referenceNumber},
|
||||
{'b', NULL, "blockSize -- contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.blockSize},
|
||||
{'B', NULL, "useO_DIRECT -- uses O_DIRECT for POSIX, bypassing I/O buffers", OPTION_FLAG, 'd', & initialTestParams.useO_DIRECT},
|
||||
{'c', NULL, "collective -- collective I/O", OPTION_FLAG, 'd', & initialTestParams.collective},
|
||||
{'C', NULL, "reorderTasks -- changes task ordering to n+1 ordering for readback", OPTION_FLAG, 'd', & initialTestParams.reorderTasks},
|
||||
{'d', NULL, "interTestDelay -- delay between reps in seconds", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.interTestDelay},
|
||||
{'D', NULL, "deadlineForStonewalling -- seconds before stopping write or read phase", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.deadlineForStonewalling},
|
||||
{.help=" -O stoneWallingWearOut=1 -- once the stonewalling timout is over, all process finish to access the amount of data", .arg = OPTION_OPTIONAL_ARGUMENT},
|
||||
{.help=" -O stoneWallingWearOutIterations=N -- stop after processing this number of iterations, needed for reading data back written with stoneWallingWearOut", .arg = OPTION_OPTIONAL_ARGUMENT},
|
||||
{.help=" -O stoneWallingStatusFile=FILE -- this file keeps the number of iterations from stonewalling during write and allows to use them for read", .arg = OPTION_OPTIONAL_ARGUMENT},
|
||||
{'e', NULL, "fsync -- perform fsync/msync upon POSIX/MMAP write close", OPTION_FLAG, 'd', & initialTestParams.fsync},
|
||||
{'E', NULL, "useExistingTestFile -- do not remove test file before write access", OPTION_FLAG, 'd', & initialTestParams.useExistingTestFile},
|
||||
{'f', NULL, "scriptFile -- test script name", OPTION_FLAG, 'd', & testscripts},
|
||||
{'F', NULL, "filePerProc -- file-per-process", OPTION_FLAG, 'd', & initialTestParams.filePerProc},
|
||||
{'g', NULL, "intraTestBarriers -- use barriers between open, write/read, and close", OPTION_FLAG, 'd', & initialTestParams.intraTestBarriers},
|
||||
/* This option toggles between Incompressible Seed and Time stamp sig based on -l,
|
||||
* so we'll toss the value in both for now, and sort it out in initialization
|
||||
* after all the arguments are in and we know which it keep.
|
||||
*/
|
||||
{'G', NULL, "setTimeStampSignature -- set value for time stamp signature/random seed", OPTION_FLAG, 'd', & toggleG},
|
||||
{'H', NULL, "showHints -- show hints", OPTION_FLAG, 'd', & initialTestParams.showHints},
|
||||
{'i', NULL, "repetitions -- number of repetitions of test", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.repetitions},
|
||||
{'I', NULL, "individualDataSets -- datasets not shared by all procs [not working]", OPTION_FLAG, 'd', & initialTestParams.individualDataSets},
|
||||
{'j', NULL, "outlierThreshold -- warn on outlier N seconds from mean", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.outlierThreshold},
|
||||
{'J', NULL, "setAlignment -- HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.setAlignment},
|
||||
{'k', NULL, "keepFile -- don't remove the test file(s) on program exit", OPTION_FLAG, 'd', & initialTestParams.keepFile},
|
||||
{'K', NULL, "keepFileWithError -- keep error-filled file(s) after data-checking", OPTION_FLAG, 'd', & initialTestParams.keepFileWithError},
|
||||
{'l', NULL, "datapacket type-- type of packet that will be created [offset|incompressible|timestamp|o|i|t]", OPTION_OPTIONAL_ARGUMENT, 's', & buffer_type},
|
||||
{'m', NULL, "multiFile -- use number of reps (-i) for multiple file count", OPTION_FLAG, 'd', & initialTestParams.multiFile},
|
||||
{'M', NULL, "memoryPerNode -- hog memory on the node (e.g.: 2g, 75%)", OPTION_OPTIONAL_ARGUMENT, 's', & memoryPerNode},
|
||||
{'n', NULL, "noFill -- no fill in HDF5 file creation", OPTION_FLAG, 'd', & initialTestParams.noFill},
|
||||
{'N', NULL, "numTasks -- number of tasks that should participate in the test", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.numTasks},
|
||||
{'o', NULL, "testFile -- full name for test", OPTION_OPTIONAL_ARGUMENT, 's', & initialTestParams.testFileName},
|
||||
{'O', NULL, "string of IOR directives (e.g. -O checkRead=1,lustreStripeCount=32)", OPTION_OPTIONAL_ARGUMENT, 'p', & decodeDirectiveWrapper},
|
||||
{'p', NULL, "preallocate -- preallocate file size", OPTION_FLAG, 'd', & initialTestParams.preallocate},
|
||||
{'P', NULL, "useSharedFilePointer -- use shared file pointer [not working]", OPTION_FLAG, 'd', & initialTestParams.useSharedFilePointer},
|
||||
{'q', NULL, "quitOnError -- during file error-checking, abort on error", OPTION_FLAG, 'd', & initialTestParams.quitOnError},
|
||||
{'Q', NULL, "taskPerNodeOffset for read tests use with -C & -Z options (-C constant N, -Z at least N)", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.taskPerNodeOffset},
|
||||
{'r', NULL, "readFile -- read existing file", OPTION_FLAG, 'd', & initialTestParams.readFile},
|
||||
{'R', NULL, "checkRead -- verify that the output of read matches the expected signature (used with -G)", OPTION_FLAG, 'd', & initialTestParams.checkRead},
|
||||
{'s', NULL, "segmentCount -- number of segments", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.segmentCount},
|
||||
{'S', NULL, "useStridedDatatype -- put strided access into datatype [not working]", OPTION_FLAG, 'd', & initialTestParams.useStridedDatatype},
|
||||
{'t', NULL, "transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'l', & initialTestParams.transferSize},
|
||||
{'T', NULL, "maxTimeDuration -- max time in minutes executing repeated test; it aborts only between iterations and not within a test!", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.maxTimeDuration},
|
||||
{'u', NULL, "uniqueDir -- use unique directory name for each file-per-process", OPTION_FLAG, 'd', & initialTestParams.uniqueDir},
|
||||
{'U', NULL, "hintsFileName -- full name for hints file", OPTION_OPTIONAL_ARGUMENT, 's', & initialTestParams.hintsFileName},
|
||||
{'v', NULL, "verbose -- output information (repeating flag increases level)", OPTION_FLAG, 'd', & initialTestParams.verbose},
|
||||
{'V', NULL, "useFileView -- use MPI_File_set_view", OPTION_FLAG, 'd', & initialTestParams.useFileView},
|
||||
{'w', NULL, "writeFile -- write file", OPTION_FLAG, 'd', & initialTestParams.writeFile},
|
||||
{'W', NULL, "checkWrite -- check read after write", OPTION_FLAG, 'd', & initialTestParams.checkWrite},
|
||||
{'x', NULL, "singleXferAttempt -- do not retry transfer if incomplete", OPTION_FLAG, 'd', & initialTestParams.singleXferAttempt},
|
||||
{'X', NULL, "reorderTasksRandomSeed -- random seed for -Z option", OPTION_OPTIONAL_ARGUMENT, 'd', & initialTestParams.reorderTasksRandomSeed},
|
||||
{'Y', NULL, "fsyncPerWrite -- perform fsync/msync after each POSIX/MMAP write", OPTION_FLAG, 'd', & initialTestParams.fsyncPerWrite},
|
||||
{'z', NULL, "randomOffset -- access is to random, not sequential, offsets within a file", OPTION_FLAG, 'd', & initialTestParams.randomOffset},
|
||||
{'Z', NULL, "reorderTasksRandom -- changes task ordering to random ordering for readback", OPTION_FLAG, 'd', & initialTestParams.reorderTasksRandom},
|
||||
{.help=" -O summaryFile=FILE -- store result data into this file", .arg = OPTION_OPTIONAL_ARGUMENT},
|
||||
{.help=" -O summaryFormat=[default,JSON,CSV] -- use the format for outputing the summary", .arg = OPTION_OPTIONAL_ARGUMENT},
|
||||
LAST_OPTION,
|
||||
};
|
||||
|
||||
int i;
|
||||
IOR_test_t *tests = NULL;
|
||||
char * optarg;
|
||||
|
||||
init_IOR_Param_t(&initialTestParams);
|
||||
GetPlatformName(initialTestParams.platform);
|
||||
initialTestParams.writeFile = initialTestParams.readFile = FALSE;
|
||||
initialTestParams.checkWrite = initialTestParams.checkRead = FALSE;
|
||||
int printhelp = 0;
|
||||
int parsed_options = option_parse(argc, argv, options, & printhelp);
|
||||
|
||||
option_t *optList, *thisOpt;
|
||||
optList = GetOptList(argc, argv, opts);
|
||||
|
||||
while (optList != NULL) {
|
||||
thisOpt = optList;
|
||||
optarg = thisOpt->argument;
|
||||
optList = optList->next;
|
||||
switch (thisOpt->option) {
|
||||
case 'a':
|
||||
strcpy(initialTestParams.api, optarg);
|
||||
break;
|
||||
case 'A':
|
||||
initialTestParams.referenceNumber = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
initialTestParams.blockSize = StringToBytes(optarg);
|
||||
RecalculateExpectedFileSize(&initialTestParams);
|
||||
break;
|
||||
case 'B':
|
||||
initialTestParams.useO_DIRECT = TRUE;
|
||||
break;
|
||||
case 'c':
|
||||
initialTestParams.collective = TRUE;
|
||||
break;
|
||||
case 'C':
|
||||
initialTestParams.reorderTasks = TRUE;
|
||||
break;
|
||||
case 'd':
|
||||
initialTestParams.interTestDelay = atoi(optarg);
|
||||
break;
|
||||
case 'D':
|
||||
initialTestParams.deadlineForStonewalling =
|
||||
atoi(optarg);
|
||||
break;
|
||||
case 'e':
|
||||
initialTestParams.fsync = TRUE;
|
||||
break;
|
||||
case 'E':
|
||||
initialTestParams.useExistingTestFile = TRUE;
|
||||
break;
|
||||
case 'f':
|
||||
tests = ReadConfigScript(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
initialTestParams.filePerProc = TRUE;
|
||||
break;
|
||||
case 'g':
|
||||
initialTestParams.intraTestBarriers = TRUE;
|
||||
break;
|
||||
case 'G':
|
||||
/* This option toggles between Incompressible Seed and Time stamp sig based on -l,
|
||||
* so we'll toss the value in both for now, and sort it out in initialization
|
||||
* after all the arguments are in and we know which it keep.
|
||||
*/
|
||||
initialTestParams.setTimeStampSignature = atoi(optarg);
|
||||
initialTestParams.incompressibleSeed = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
initialTestParams.showHelp = TRUE;
|
||||
break;
|
||||
case 'H':
|
||||
initialTestParams.showHints = TRUE;
|
||||
break;
|
||||
case 'i':
|
||||
initialTestParams.repetitions = atoi(optarg);
|
||||
break;
|
||||
case 'I':
|
||||
initialTestParams.individualDataSets = TRUE;
|
||||
break;
|
||||
case 'j':
|
||||
initialTestParams.outlierThreshold = atoi(optarg);
|
||||
break;
|
||||
case 'J':
|
||||
initialTestParams.setAlignment = StringToBytes(optarg);
|
||||
break;
|
||||
case 'k':
|
||||
initialTestParams.keepFile = TRUE;
|
||||
break;
|
||||
case 'K':
|
||||
initialTestParams.keepFileWithError = TRUE;
|
||||
break;
|
||||
case 'l':
|
||||
switch(*optarg) {
|
||||
case 'i': /* Incompressible */
|
||||
initialTestParams.dataPacketType = incompressible;
|
||||
break;
|
||||
case 't': /* timestamp */
|
||||
initialTestParams.dataPacketType = timestamp;
|
||||
break;
|
||||
case 'o': /* offset packet */
|
||||
initialTestParams.storeFileOffset = TRUE;
|
||||
initialTestParams.dataPacketType = offset;
|
||||
break;
|
||||
default:
|
||||
fprintf(out_logfile,
|
||||
"Unknown arguement for -l %s generic assumed\n", optarg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
initialTestParams.multiFile = TRUE;
|
||||
break;
|
||||
case 'M':
|
||||
initialTestParams.memoryPerNode =
|
||||
NodeMemoryStringToBytes(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
initialTestParams.noFill = TRUE;
|
||||
break;
|
||||
case 'N':
|
||||
initialTestParams.numTasks = atoi(optarg);
|
||||
RecalculateExpectedFileSize(&initialTestParams);
|
||||
break;
|
||||
case 'o':
|
||||
strcpy(initialTestParams.testFileName, optarg);
|
||||
break;
|
||||
case 'O':
|
||||
ParseLine(optarg, &initialTestParams);
|
||||
break;
|
||||
case 'p':
|
||||
initialTestParams.preallocate = TRUE;
|
||||
break;
|
||||
case 'P':
|
||||
initialTestParams.useSharedFilePointer = TRUE;
|
||||
break;
|
||||
case 'q':
|
||||
initialTestParams.quitOnError = TRUE;
|
||||
break;
|
||||
case 'Q':
|
||||
initialTestParams.taskPerNodeOffset = atoi(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
initialTestParams.readFile = TRUE;
|
||||
break;
|
||||
case 'R':
|
||||
initialTestParams.checkRead = TRUE;
|
||||
break;
|
||||
case 's':
|
||||
initialTestParams.segmentCount = atoi(optarg);
|
||||
RecalculateExpectedFileSize(&initialTestParams);
|
||||
break;
|
||||
case 'S':
|
||||
initialTestParams.useStridedDatatype = TRUE;
|
||||
break;
|
||||
case 't':
|
||||
initialTestParams.transferSize = StringToBytes(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
initialTestParams.maxTimeDuration = atoi(optarg);
|
||||
break;
|
||||
case 'u':
|
||||
initialTestParams.uniqueDir = TRUE;
|
||||
break;
|
||||
case 'U':
|
||||
strcpy(initialTestParams.hintsFileName, optarg);
|
||||
break;
|
||||
case 'v':
|
||||
initialTestParams.verbose++;
|
||||
break;
|
||||
case 'V':
|
||||
initialTestParams.useFileView = TRUE;
|
||||
break;
|
||||
case 'w':
|
||||
initialTestParams.writeFile = TRUE;
|
||||
break;
|
||||
case 'W':
|
||||
initialTestParams.checkWrite = TRUE;
|
||||
break;
|
||||
case 'x':
|
||||
initialTestParams.singleXferAttempt = TRUE;
|
||||
break;
|
||||
case 'X':
|
||||
initialTestParams.reorderTasksRandomSeed = atoi(optarg);
|
||||
break;
|
||||
case 'Y':
|
||||
initialTestParams.fsyncPerWrite = TRUE;
|
||||
break;
|
||||
case 'z':
|
||||
initialTestParams.randomOffset = TRUE;
|
||||
break;
|
||||
case 'Z':
|
||||
initialTestParams.reorderTasksRandom = TRUE;
|
||||
break;
|
||||
default:
|
||||
fprintf(out_logfile,
|
||||
"ParseCommandLine: unknown option `-%c'.\n",
|
||||
optopt);
|
||||
}
|
||||
if (toggleG){
|
||||
initialTestParams.setTimeStampSignature = toggleG;
|
||||
initialTestParams.incompressibleSeed = toggleG;
|
||||
}
|
||||
|
||||
tests = CreateTest(&initialTestParams, 0);
|
||||
AllocResults(tests);
|
||||
if (buffer_type[0] != 0){
|
||||
switch(buffer_type[0]) {
|
||||
case 'i': /* Incompressible */
|
||||
initialTestParams.dataPacketType = incompressible;
|
||||
break;
|
||||
case 't': /* timestamp */
|
||||
initialTestParams.dataPacketType = timestamp;
|
||||
break;
|
||||
case 'o': /* offset packet */
|
||||
initialTestParams.storeFileOffset = TRUE;
|
||||
initialTestParams.dataPacketType = offset;
|
||||
break;
|
||||
default:
|
||||
fprintf(out_logfile,
|
||||
"Unknown arguement for -l %s; generic assumed\n", buffer_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (memoryPerNode){
|
||||
initialTestParams.memoryPerNode = NodeMemoryStringToBytes(optarg);
|
||||
}
|
||||
|
||||
/* get the version of the tests */
|
||||
|
||||
const ior_aiori_t * backend = aiori_select(initialTestParams.api);
|
||||
initialTestParams.backend = backend;
|
||||
initialTestParams.apiVersion = backend->get_version();
|
||||
|
||||
if(printhelp != 0){
|
||||
printf("Usage: %s ", argv[0]);
|
||||
|
||||
option_print_help(options, 0);
|
||||
|
||||
if(backend->get_options != NULL){
|
||||
printf("\nPlugin options for backend %s (%s)\n", initialTestParams.api, backend->get_version());
|
||||
option_print_help(backend->get_options(), 1);
|
||||
}
|
||||
if(printhelp == 1){
|
||||
exit(0);
|
||||
}else{
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (testscripts){
|
||||
tests = ReadConfigScript(testscripts);
|
||||
}else{
|
||||
tests = CreateTest(&initialTestParams, 0);
|
||||
}
|
||||
|
||||
CheckRunSettings(tests);
|
||||
|
||||
|
|
Loading…
Reference in New Issue