Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
2153aaf6
Commit
2153aaf6
authored
Jan 15, 2019
by
Vladislav Vaintroub
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mariabackup : use die() macro for fatal exit with error message.
parent
a8a27e65
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
63 additions
and
90 deletions
+63
-90
extra/mariabackup/backup_copy.cc
extra/mariabackup/backup_copy.cc
+2
-3
extra/mariabackup/backup_mysql.cc
extra/mariabackup/backup_mysql.cc
+5
-6
extra/mariabackup/common.h
extra/mariabackup/common.h
+18
-11
extra/mariabackup/datasink.cc
extra/mariabackup/datasink.cc
+3
-6
extra/mariabackup/ds_buffer.cc
extra/mariabackup/ds_buffer.cc
+1
-1
extra/mariabackup/ds_tmpfile.cc
extra/mariabackup/ds_tmpfile.cc
+5
-9
extra/mariabackup/encryption_plugin.cc
extra/mariabackup/encryption_plugin.cc
+1
-2
extra/mariabackup/wsrep.cc
extra/mariabackup/wsrep.cc
+3
-4
extra/mariabackup/xtrabackup.cc
extra/mariabackup/xtrabackup.cc
+25
-48
No files found.
extra/mariabackup/backup_copy.cc
View file @
2153aaf6
...
...
@@ -2221,7 +2221,7 @@ static void copy_or_move_dir(const char *from, const char *to, bool do_copy, boo
to
,
1
));
}
if
(
!
rc
)
exit
(
EXIT_FAILURE
);
die
(
"copy or move file failed"
);
}
datadir_iter_free
(
it
);
datadir_node_free
(
&
node
);
...
...
@@ -2323,8 +2323,7 @@ static void rocksdb_backup_checkpoint()
if
(
backup_to_directory
)
{
if
(
my_mkdir
(
rocksdb_backup_dir
,
0777
,
MYF
(
0
))){
msg
(
"Can't create rocksdb backup directory %s"
,
rocksdb_backup_dir
);
exit
(
EXIT_FAILURE
);
die
(
"Can't create rocksdb backup directory %s"
,
rocksdb_backup_dir
);
}
}
copy_or_move_dir
(
rocksdb_checkpoint_dir
,
ROCKSDB_BACKUP_DIR
,
true
,
backup_to_directory
);
...
...
extra/mariabackup/backup_mysql.cc
View file @
2153aaf6
...
...
@@ -167,9 +167,10 @@ xb_mysql_query(MYSQL *connection, const char *query, bool use_result,
MYSQL_RES
*
mysql_result
=
NULL
;
if
(
mysql_query
(
connection
,
query
))
{
msg
(
"Error: failed to execute query %s: %s"
,
query
,
mysql_error
(
connection
));
if
(
die_on_error
)
{
exit
(
EXIT_FAILURE
);
die
(
"failed to execute query %s: %s"
,
query
,
mysql_error
(
connection
));
}
else
{
msg
(
"Error: failed to execute query %s: %s"
,
query
,
mysql_error
(
connection
));
}
return
(
NULL
);
}
...
...
@@ -177,9 +178,8 @@ xb_mysql_query(MYSQL *connection, const char *query, bool use_result,
/* store result set on client if there is a result */
if
(
mysql_field_count
(
connection
)
>
0
)
{
if
((
mysql_result
=
mysql_store_result
(
connection
))
==
NULL
)
{
msg
(
"Error:
failed to fetch query result %s: %s"
,
die
(
"
failed to fetch query result %s: %s"
,
query
,
mysql_error
(
connection
));
exit
(
EXIT_FAILURE
);
}
if
(
!
use_result
)
{
...
...
@@ -910,8 +910,7 @@ DECLARE_THREAD(kill_mdl_waiters_thread(void *))
row
[
1
],
row
[
2
],
row
[
0
]);
snprintf
(
query
,
sizeof
(
query
),
"KILL QUERY %s"
,
row
[
0
]);
if
(
mysql_query
(
mysql
,
query
)
&&
(
mysql_errno
(
mysql
)
!=
ER_NO_SUCH_THREAD
))
{
msg
(
"Error: failed to execute query %s: %s"
,
query
,
mysql_error
(
mysql
));
exit
(
EXIT_FAILURE
);
die
(
"failed to execute query %s: %s"
,
query
,
mysql_error
(
mysql
));
}
}
mysql_free_result
(
result
);
...
...
extra/mariabackup/common.h
View file @
2153aaf6
...
...
@@ -86,9 +86,7 @@ static inline int asprintf(char **strp, const char *fmt,...)
#define XB_DELTA_INFO_SUFFIX ".meta"
static
inline
int
msg1
(
unsigned
int
thread_num
,
const
char
*
fmt
,
...)
ATTRIBUTE_FORMAT
(
printf
,
2
,
3
);
static
inline
int
msg1
(
uint
thread_num
,
const
char
*
fmt
,
va_list
args
)
static
inline
int
msg1
(
uint
thread_num
,
const
char
*
prefix
,
const
char
*
fmt
,
va_list
args
)
{
int
result
;
time_t
t
=
time
(
NULL
);
...
...
@@ -98,35 +96,44 @@ static inline int msg1(uint thread_num, const char *fmt, va_list args)
result
=
vasprintf
(
&
line
,
fmt
,
args
);
if
(
result
!=
-
1
)
{
if
(
fmt
&&
fmt
[
strlen
(
fmt
)]
!=
'\n'
)
result
=
fprintf
(
stderr
,
"[%02u] %s
%s
\n
"
,
thread_num
,
date
,
line
);
result
=
fprintf
(
stderr
,
"[%02u] %s
%s %s
\n
"
,
thread_num
,
prefix
,
date
,
line
);
else
result
=
fprintf
(
stderr
,
"[%02u] %s
%s"
,
thread_num
,
date
,
line
);
result
=
fprintf
(
stderr
,
"[%02u] %s
%s %s"
,
thread_num
,
prefix
,
date
,
line
);
free
(
line
);
}
return
result
;
}
static
inline
int
msg
(
unsigned
int
,
const
char
*
fmt
,
...)
ATTRIBUTE_FORMAT
(
printf
,
2
,
3
);
static
inline
int
msg
(
unsigned
int
thread_num
,
const
char
*
fmt
,
...)
static
inline
ATTRIBUTE_FORMAT
(
printf
,
2
,
3
)
int
msg
(
unsigned
int
thread_num
,
const
char
*
fmt
,
...)
{
int
result
;
va_list
args
;
va_start
(
args
,
fmt
);
result
=
msg1
(
thread_num
,
fmt
,
args
);
result
=
msg1
(
thread_num
,
""
,
fmt
,
args
);
va_end
(
args
);
return
result
;
}
static
inline
int
msg
(
const
char
*
fmt
,
...)
ATTRIBUTE_FORMAT
(
printf
,
1
,
2
);
static
inline
int
msg
(
const
char
*
fmt
,
...)
static
inline
ATTRIBUTE_FORMAT
(
printf
,
1
,
2
)
int
msg
(
const
char
*
fmt
,
...)
{
int
result
;
va_list
args
;
va_start
(
args
,
fmt
);
result
=
msg1
(
0
,
fmt
,
args
);
result
=
msg1
(
0
,
""
,
fmt
,
args
);
va_end
(
args
);
return
result
;
}
static
inline
ATTRIBUTE_FORMAT
(
printf
,
1
,
2
)
ATTRIBUTE_NORETURN
void
die
(
const
char
*
fmt
,
...)
{
va_list
args
;
va_start
(
args
,
fmt
);
msg1
(
0
,
"FATAL ERROR: "
,
fmt
,
args
);
va_end
(
args
);
fflush
(
stderr
);
_exit
(
EXIT_FAILURE
);
}
/* Use POSIX_FADV_NORMAL when available */
...
...
extra/mariabackup/datasink.cc
View file @
2153aaf6
...
...
@@ -48,8 +48,7 @@ ds_create(const char *root, ds_type_t type)
#ifdef HAVE_LIBARCHIVE
ds
=
&
datasink_archive
;
#else
msg
(
"Error : mariabackup was built without libarchive support"
);
exit
(
EXIT_FAILURE
);
die
(
"mariabackup was built without libarchive support"
);
#endif
break
;
case
DS_TYPE_XBSTREAM
:
...
...
@@ -60,8 +59,7 @@ ds_create(const char *root, ds_type_t type)
break
;
case
DS_TYPE_ENCRYPT
:
case
DS_TYPE_DECRYPT
:
msg
(
"Error : mariabackup does not support encrypted backups."
);
exit
(
EXIT_FAILURE
);
die
(
"mariabackup does not support encrypted backups."
);
break
;
case
DS_TYPE_TMPFILE
:
...
...
@@ -80,8 +78,7 @@ ds_create(const char *root, ds_type_t type)
if
(
ctxt
!=
NULL
)
{
ctxt
->
datasink
=
ds
;
}
else
{
msg
(
"Error: failed to initialize datasink."
);
exit
(
EXIT_FAILURE
);
die
(
"failed to initialize datasink."
);
}
return
ctxt
;
...
...
extra/mariabackup/ds_buffer.cc
View file @
2153aaf6
...
...
@@ -96,7 +96,7 @@ buffer_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat)
dst_file
=
ds_open
(
pipe_ctxt
,
path
,
mystat
);
if
(
dst_file
==
NULL
)
{
exit
(
EXIT_FAILURE
);
die
(
"ds_open(%s) failed"
,
path
);
}
buffer_ctxt
=
(
ds_buffer_ctxt_t
*
)
ctxt
->
ptr
;
...
...
extra/mariabackup/ds_tmpfile.cc
View file @
2153aaf6
...
...
@@ -195,8 +195,7 @@ tmpfile_deinit(ds_ctxt_t *ctxt)
/* Stat the file to replace size and mtime on the original
* mystat struct */
if
(
my_fstat
(
tmp_file
->
fd
,
&
mystat
,
MYF
(
0
)))
{
msg
(
"error: my_fstat() failed."
);
exit
(
EXIT_FAILURE
);
die
(
"my_fstat() failed."
);
}
tmp_file
->
mystat
.
st_size
=
mystat
.
st_size
;
tmp_file
->
mystat
.
st_mtime
=
mystat
.
st_mtime
;
...
...
@@ -204,18 +203,16 @@ tmpfile_deinit(ds_ctxt_t *ctxt)
dst_file
=
ds_open
(
pipe_ctxt
,
tmp_file
->
orig_path
,
&
tmp_file
->
mystat
);
if
(
dst_file
==
NULL
)
{
msg
(
"error:
could not stream a temporary file to "
die
(
"
could not stream a temporary file to "
"'%s'"
,
tmp_file
->
orig_path
);
exit
(
EXIT_FAILURE
);
}
/* copy to the destination datasink */
posix_fadvise
(
tmp_file
->
fd
,
0
,
0
,
POSIX_FADV_SEQUENTIAL
);
if
(
my_seek
(
tmp_file
->
fd
,
0
,
SEEK_SET
,
MYF
(
0
))
==
MY_FILEPOS_ERROR
)
{
msg
(
"error:
my_seek() failed for '%s', errno = %d."
,
die
(
"
my_seek() failed for '%s', errno = %d."
,
tmp_file
->
file
->
path
,
my_errno
);
exit
(
EXIT_FAILURE
);
}
offset
=
0
;
while
((
bytes
=
my_read
(
tmp_file
->
fd
,
(
unsigned
char
*
)
buf
,
buf_size
,
...
...
@@ -223,13 +220,12 @@ tmpfile_deinit(ds_ctxt_t *ctxt)
posix_fadvise
(
tmp_file
->
fd
,
offset
,
buf_size
,
POSIX_FADV_DONTNEED
);
offset
+=
buf_size
;
if
(
ds_write
(
dst_file
,
buf
,
bytes
))
{
msg
(
"error:
cannot write to stream for '%s'."
,
die
(
"
cannot write to stream for '%s'."
,
tmp_file
->
orig_path
);
exit
(
EXIT_FAILURE
);
}
}
if
(
bytes
==
(
size_t
)
-
1
)
{
exit
(
EXIT_FAILURE
);
die
(
"my_read failed for %s"
,
tmp_file
->
orig_path
);
}
my_close
(
tmp_file
->
fd
,
MYF
(
MY_WME
));
...
...
extra/mariabackup/encryption_plugin.cc
View file @
2153aaf6
...
...
@@ -45,8 +45,7 @@ static std::string get_encryption_plugin_from_cnf()
FILE
*
f
=
fopen
(
"backup-my.cnf"
,
"r"
);
if
(
!
f
)
{
msg
(
"Can't open backup-my.cnf for reading"
);
exit
(
EXIT_FAILURE
);
die
(
"Can't open backup-my.cnf for reading"
);
}
char
line
[
512
];
std
::
string
plugin_load
;
...
...
extra/mariabackup/wsrep.cc
View file @
2153aaf6
...
...
@@ -193,7 +193,7 @@ xb_write_galera_info(bool incremental_prepare)
fp
=
fopen
(
XB_GALERA_INFO_FILENAME
,
"w"
);
if
(
fp
==
NULL
)
{
msg
(
"mariabackup: error: "
die
(
"could not create "
XB_GALERA_INFO_FILENAME
", errno = %d
\n
"
,
errno
);
...
...
@@ -207,11 +207,10 @@ xb_write_galera_info(bool incremental_prepare)
if
(
fprintf
(
fp
,
"%s:%lld"
,
uuid_str
,
(
long
long
)
seqno
)
<
0
)
{
msg
(
"mariabackup: error: "
die
(
"could not write to "
XB_GALERA_INFO_FILENAME
", errno = %d
\n
"
,
errno
);
exit
(
EXIT_FAILURE
);
errno
);;
}
fclose
(
fp
);
...
...
extra/mariabackup/xtrabackup.cc
View file @
2153aaf6
...
...
@@ -657,9 +657,8 @@ static void backup_file_op_fail(ulint space_id, const byte* flags,
msg
(
"DDL tracking : delete %zu
\"
%.*s
\"
"
,
space_id
,
int
(
len
),
name
);
}
if
(
fail
)
{
msg
(
"ERROR :
DDL operation detected in the late phase of backup."
die
(
"
DDL operation detected in the late phase of backup."
"Backup is inconsistent. Remove --no-lock option to fix."
);
exit
(
EXIT_FAILURE
);
}
}
...
...
@@ -1457,8 +1456,7 @@ debug_sync_point(const char *name)
xtrabackup_target_dir
);
fp
=
fopen
(
pid_path
,
"w"
);
if
(
fp
==
NULL
)
{
msg
(
"mariabackup: Error: cannot open %s"
,
pid_path
);
exit
(
EXIT_FAILURE
);
die
(
"Can't open open %s"
,
pid_path
);
}
fprintf
(
fp
,
"%u
\n
"
,
(
uint
)
pid
);
fclose
(
fp
);
...
...
@@ -1794,7 +1792,7 @@ innodb_init_param(void)
memset
((
G_PTR
)
&
mysql_tmpdir_list
,
0
,
sizeof
(
mysql_tmpdir_list
));
if
(
init_tmpdir
(
&
mysql_tmpdir_list
,
opt_mysql_tmpdir
))
exit
(
EXIT_FAILURE
);
die
(
"init_tmpdir() failed"
);
xtrabackup_tmpdir
=
my_tmpdir
(
&
mysql_tmpdir_list
);
/* dummy for initialize all_charsets[] */
get_charset_name
(
0
);
...
...
@@ -1811,9 +1809,8 @@ innodb_init_param(void)
msg
(
"InnoDB: The page size of the "
"database is set to %lu."
,
srv_page_size
);
}
else
{
msg
(
"InnoDB: Error:
invalid value of "
die
(
"
invalid value of "
"innobase_page_size: %lld"
,
innobase_page_size
);
exit
(
EXIT_FAILURE
);
}
}
else
{
srv_page_size_shift
=
14
;
...
...
@@ -2766,8 +2763,7 @@ static bool xtrabackup_copy_logfile(bool last = false)
log_mutex_exit
();
if
(
!
start_lsn
)
{
msg
(
"Error: xtrabackup_copy_logfile() failed."
);
exit
(
EXIT_FAILURE
);
die
(
"xtrabackup_copy_logfile() failed."
);
}
}
while
(
start_lsn
==
end_lsn
);
...
...
@@ -2916,8 +2912,7 @@ data_copy_thread_func(
DBUG_MARIABACKUP_EVENT
(
"before_copy"
,
node
->
space
->
name
);
/* copy the datafile */
if
(
xtrabackup_copy_datafile
(
node
,
num
))
{
msg
(
num
,
"mariabackup: Error: failed to copy datafile."
);
exit
(
EXIT_FAILURE
);
die
(
"failed to copy datafile."
);
}
DBUG_MARIABACKUP_EVENT
(
"after_copy"
,
node
->
space
->
name
);
...
...
@@ -3094,9 +3089,7 @@ xb_load_single_table_tablespace(
Datafile
*
file
=
xb_new_datafile
(
name
,
is_remote
);
if
(
file
->
open_read_only
(
true
)
!=
DB_SUCCESS
)
{
msg
(
"Can't open datafile %s"
,
name
);
ut_free
(
name
);
exit
(
EXIT_FAILURE
);
die
(
"Can't open datafile %s"
,
name
);
}
err
=
file
->
validate_first_page
(
&
flush_lsn
);
...
...
@@ -3134,7 +3127,7 @@ xb_load_single_table_tablespace(
if
(
err
!=
DB_SUCCESS
&&
err
!=
DB_CORRUPTION
&&
xtrabackup_backup
)
{
/* allow corrupted first page for xtrabackup, it could be just
zero-filled page, which we restore from redo log later */
exit
(
EXIT_FAILURE
);
die
(
"Failed to not validate first page of the file %s, error %d"
,
name
,
(
int
)
err
);
}
}
...
...
@@ -3505,13 +3498,11 @@ xb_validate_name(
/* perform only basic validation. validate length and
path symbols */
if
(
len
>
NAME_LEN
)
{
msg
(
"mariabackup: name `%s` is too long."
,
name
);
exit
(
EXIT_FAILURE
);
die
(
"name `%s` is too long."
,
name
);
}
p
=
strpbrk
(
name
,
"/
\\
~"
);
if
(
p
&&
(
uint
)
(
p
-
name
)
<
NAME_LEN
)
{
msg
(
"mariabackup: name `%s` is not valid."
,
name
);
exit
(
EXIT_FAILURE
);
die
(
"name `%s` is not valid."
,
name
);
}
}
...
...
@@ -3589,8 +3580,7 @@ xb_register_table(
const
char
*
name
)
/*!< in: name of table */
{
if
(
strchr
(
name
,
'.'
)
==
NULL
)
{
msg
(
"mariabackup: `%s` is not fully qualified name."
,
name
);
exit
(
EXIT_FAILURE
);
die
(
"`%s` is not fully qualified name."
,
name
);
}
xb_register_include_filter_entry
(
name
);
...
...
@@ -3680,17 +3670,15 @@ xb_load_list_file(
/* read and store the filenames */
fp
=
fopen
(
filename
,
"r"
);
if
(
!
fp
)
{
msg
(
"mariabackup: canno
t open %s"
,
die
(
"Can'
t open %s"
,
filename
);
exit
(
EXIT_FAILURE
);
}
while
(
fgets
(
name_buf
,
sizeof
(
name_buf
),
fp
)
!=
NULL
)
{
char
*
p
=
strchr
(
name_buf
,
'\n'
);
if
(
p
)
{
*
p
=
'\0'
;
}
else
{
msg
(
"mariabackup: `%s...` name is too long"
,
name_buf
);
exit
(
EXIT_FAILURE
);
die
(
"`%s...` name is too long"
,
name_buf
);
}
ins
(
name_buf
);
...
...
@@ -4797,9 +4785,8 @@ xb_delta_open_matching_space(
if
(
info
.
space_id
==
ULINT_UNDEFINED
)
{
msg
(
"mariabackup: Error: Canno
t handle DDL operation on tablespace "
die
(
"Can'
t handle DDL operation on tablespace "
"%s
\n
"
,
dest_space_name
);
exit
(
EXIT_FAILURE
);
}
mutex_enter
(
&
fil_system
->
mutex
);
fil_space
=
fil_space_get_by_id
(
info
.
space_id
);
...
...
@@ -5093,8 +5080,7 @@ std::string change_extension(std::string filename, std::string new_ext) {
static
void
rename_file
(
const
char
*
from
,
const
char
*
to
)
{
msg
(
"Renaming %s to %s
\n
"
,
from
,
to
);
if
(
my_rename
(
from
,
to
,
MY_WME
))
{
msg
(
"Can't rename %s to %s errno %d"
,
from
,
to
,
errno
);
exit
(
EXIT_FAILURE
);
die
(
"Can't rename %s to %s errno %d"
,
from
,
to
,
errno
);
}
}
...
...
@@ -5371,8 +5357,7 @@ static void delete_file(const std::string& file, bool if_exists = false) {
if
(
if_exists
&&
!
file_exists
(
file
))
return
;
if
(
my_delete
(
file
.
c_str
(),
MYF
(
MY_WME
)))
{
msg
(
"Can't remove %s, errno %d"
,
file
.
c_str
(),
errno
);
exit
(
EXIT_FAILURE
);
die
(
"Can't remove %s, errno %d"
,
file
.
c_str
(),
errno
);
}
}
...
...
@@ -5757,7 +5742,7 @@ has_privilege(const std::list<std::string> &granted,
required
,
db_name
,
table_name
);
if
(
written
<
0
||
written
==
sizeof
(
buffer
)
||
regcomp
(
&
priv_re
,
buffer
,
REG_EXTENDED
))
{
exit
(
EXIT_FAILURE
);
die
(
"regcomp() failed for '%s'"
,
buffer
);
}
typedef
std
::
list
<
std
::
string
>::
const_iterator
string_iter
;
...
...
@@ -5871,7 +5856,7 @@ check_all_privileges()
if
(
check_result
&
PRIVILEGE_ERROR
)
{
mysql_close
(
mysql_connection
);
exit
(
EXIT_FAILURE
);
die
(
"Insufficient privileges"
);
}
}
...
...
@@ -6110,21 +6095,13 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
char
*
optend
=
strcend
((
argv
)[
i
],
'='
);
if
(
optend
-
argv
[
i
]
==
15
&&
!
strncmp
(
argv
[
i
],
"--defaults-file"
,
optend
-
argv
[
i
]))
{
msg
(
"mariabackup: Error: --defaults-file "
"must be specified first on the command "
"line"
);
exit
(
EXIT_FAILURE
);
!
strncmp
(
argv
[
i
],
"--defaults-file"
,
optend
-
argv
[
i
]))
{
die
(
"--defaults-file must be specified first on the command line"
);
}
if
(
optend
-
argv
[
i
]
==
21
&&
!
strncmp
(
argv
[
i
],
"--defaults-extra-file"
,
optend
-
argv
[
i
]))
{
msg
(
"mariabackup: Error: --defaults-extra-file "
"must be specified first on the command "
"line
\n
"
);
exit
(
EXIT_FAILURE
);
if
(
optend
-
argv
[
i
]
==
21
&&
!
strncmp
(
argv
[
i
],
"--defaults-extra-file"
,
optend
-
argv
[
i
]))
{
die
(
"--defaults-extra-file must be specified first on the command line"
);
}
}
...
...
@@ -6227,7 +6204,7 @@ int main(int argc, char **argv)
if
(
mysql_server_init
(
-
1
,
NULL
,
NULL
))
{
exit
(
EXIT_FAILURE
);
die
(
"mysql_server_init() failed"
);
}
system_charset_info
=
&
my_charset_utf8_general_ci
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment