mirror of
https://github.com/upa/mscp.git
synced 2026-02-28 03:24:41 +08:00
implement ssh_connect_flag
Each copy thread establishes SSH/SFTP connection to remote host. A delay is inserted between SSH connecting to the remote.
This commit is contained in:
102
src/mscp.c
102
src/mscp.c
@@ -2,7 +2,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
@@ -13,6 +13,56 @@
|
|||||||
#include <message.h>
|
#include <message.h>
|
||||||
#include <mscp.h>
|
#include <mscp.h>
|
||||||
|
|
||||||
|
struct ssh_connect_flag {
|
||||||
|
lock lock;
|
||||||
|
struct timeval enter;
|
||||||
|
long delay; /* msec */
|
||||||
|
};
|
||||||
|
|
||||||
|
static long timeval_sub(struct timeval a, struct timeval b)
|
||||||
|
{
|
||||||
|
unsigned long sec, usec;
|
||||||
|
if (a.tv_usec < b.tv_usec) {
|
||||||
|
a.tv_usec += 1000000;
|
||||||
|
a.tv_sec--;
|
||||||
|
}
|
||||||
|
|
||||||
|
sec = a.tv_sec - b.tv_sec;
|
||||||
|
usec = a.tv_usec - b.tv_usec;
|
||||||
|
return sec * 1000000 + usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ssh_connect_flag_init(struct ssh_connect_flag *f)
|
||||||
|
{
|
||||||
|
memset(f, 0, sizeof(f));
|
||||||
|
lock_init(&f->lock);
|
||||||
|
f->delay = 10000; /* To be configurable */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ssh_connect_ready(struct ssh_connect_flag *f)
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
long delta;
|
||||||
|
|
||||||
|
LOCK_ACQUIRE_THREAD(&f->lock);
|
||||||
|
if (f->enter.tv_sec == 0 && f->enter.tv_usec == 0) {
|
||||||
|
/* I'm the first one. */
|
||||||
|
goto ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
delta = timeval_sub(now, f->enter);
|
||||||
|
if (delta <= f->delay) {
|
||||||
|
/* wait until enter + delay time */
|
||||||
|
usleep(f->delay - delta);
|
||||||
|
}
|
||||||
|
ready:
|
||||||
|
gettimeofday(&f->enter, NULL);
|
||||||
|
LOCK_RELEASE_THREAD();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct mscp {
|
struct mscp {
|
||||||
char *remote; /* remote host (and uername) */
|
char *remote; /* remote host (and uername) */
|
||||||
int direction; /* copy direction */
|
int direction; /* copy direction */
|
||||||
@@ -21,8 +71,10 @@ struct mscp {
|
|||||||
|
|
||||||
int msg_fd; /* writer fd for message pipe */
|
int msg_fd; /* writer fd for message pipe */
|
||||||
|
|
||||||
int *cores; /* usable cpu cores by COREMASK */
|
int *cores; /* usable cpu cores by COREMASK */
|
||||||
int nr_cores; /* length of array of cores */
|
int nr_cores; /* length of array of cores */
|
||||||
|
|
||||||
|
struct ssh_connect_flag ssh_flag;
|
||||||
|
|
||||||
sftp_session first; /* first sftp session */
|
sftp_session first; /* first sftp session */
|
||||||
|
|
||||||
@@ -66,6 +118,9 @@ struct src {
|
|||||||
|
|
||||||
#define non_null_string(s) (s[0] != '\0')
|
#define non_null_string(s) (s[0] != '\0')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int expand_coremask(const char *coremask, int **cores, int *nr_cores)
|
static int expand_coremask(const char *coremask, int **cores, int *nr_cores)
|
||||||
{
|
{
|
||||||
int n, *core_list, core_list_len = 0, nr_usable, nr_all;
|
int n, *core_list, core_list_len = 0, nr_usable, nr_all;
|
||||||
@@ -200,21 +255,22 @@ struct mscp *mscp_init(const char *remote_host, int direction,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mprint_set_severity(o->severity);
|
||||||
|
|
||||||
|
if (validate_and_set_defaut_params(o) < 0)
|
||||||
|
goto free_out;
|
||||||
|
|
||||||
m = malloc(sizeof(*m));
|
m = malloc(sizeof(*m));
|
||||||
if (!m) {
|
if (!m) {
|
||||||
mscp_set_error("failed to allocate memory: %s", strerrno());
|
mscp_set_error("failed to allocate memory: %s", strerrno());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mprint_set_severity(o->severity);
|
|
||||||
|
|
||||||
if (validate_and_set_defaut_params(o) < 0)
|
|
||||||
goto free_out;
|
|
||||||
|
|
||||||
memset(m, 0, sizeof(*m));
|
memset(m, 0, sizeof(*m));
|
||||||
INIT_LIST_HEAD(&m->src_list);
|
INIT_LIST_HEAD(&m->src_list);
|
||||||
INIT_LIST_HEAD(&m->path_list);
|
INIT_LIST_HEAD(&m->path_list);
|
||||||
chunk_pool_init(&m->cp);
|
chunk_pool_init(&m->cp);
|
||||||
|
ssh_connect_flag_init(&m->ssh_flag);
|
||||||
|
|
||||||
m->remote = strdup(remote_host);
|
m->remote = strdup(remote_host);
|
||||||
if (!m->remote) {
|
if (!m->remote) {
|
||||||
@@ -464,16 +520,6 @@ int mscp_start(struct mscp *m)
|
|||||||
else
|
else
|
||||||
t->cpu = m->cores[n % m->nr_cores];
|
t->cpu = m->cores[n % m->nr_cores];
|
||||||
|
|
||||||
mpr_notice(m->msg_fd, "connecting to %s for a copy thread...\n",
|
|
||||||
m->remote);
|
|
||||||
t->sftp = ssh_init_sftp_session(m->remote, m->ssh_opts);
|
|
||||||
if (!t->sftp)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* spawn copy threads */
|
|
||||||
for (n = 0; n < m->opts->nr_threads; n++) {
|
|
||||||
struct mscp_thread *t = &m->threads[n];
|
|
||||||
ret = pthread_create(&t->tid, NULL, mscp_copy_thread, t);
|
ret = pthread_create(&t->tid, NULL, mscp_copy_thread, t);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
mscp_set_error("pthread_create error: %d", ret);
|
mscp_set_error("pthread_create error: %d", ret);
|
||||||
@@ -537,6 +583,21 @@ void *mscp_copy_thread(void *arg)
|
|||||||
struct mscp *m = t->m;
|
struct mscp *m = t->m;
|
||||||
struct chunk *c;
|
struct chunk *c;
|
||||||
|
|
||||||
|
if (t->cpu > -1) {
|
||||||
|
if (set_thread_affinity(pthread_self(), t->cpu) < 0) {
|
||||||
|
t->ret = -1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_connect_ready(&m->ssh_flag);
|
||||||
|
mpr_notice(m->msg_fd, "connecting to %s for a copy thread...\n", m->remote);
|
||||||
|
t->sftp = ssh_init_sftp_session(m->remote, m->ssh_opts);
|
||||||
|
if (!t->sftp) {
|
||||||
|
t->ret = -1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
switch (m->direction) {
|
switch (m->direction) {
|
||||||
case MSCP_DIRECTION_L2R:
|
case MSCP_DIRECTION_L2R:
|
||||||
src_sftp = NULL;
|
src_sftp = NULL;
|
||||||
@@ -550,11 +611,6 @@ void *mscp_copy_thread(void *arg)
|
|||||||
return NULL; /* not reached */
|
return NULL; /* not reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->cpu > -1) {
|
|
||||||
if (set_thread_affinity(pthread_self(), t->cpu) < 0)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
|
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
|
||||||
pthread_cleanup_push(mscp_copy_thread_cleanup, t);
|
pthread_cleanup_push(mscp_copy_thread_cleanup, t);
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ static int resolve_dst_path(const char *src_file_path, char *dst_file_path,
|
|||||||
snprintf(dst_file_path, PATH_MAX - 1, "%s/%s",
|
snprintf(dst_file_path, PATH_MAX - 1, "%s/%s",
|
||||||
a->dst_path, src_file_path + strlen(a->src_path) + 1);
|
a->dst_path, src_file_path + strlen(a->src_path) + 1);
|
||||||
|
|
||||||
mpr_info(a->msg_fd, "file: %s -> %s\n", src_file_path, dst_file_path);
|
mpr_debug(a->msg_fd, "file: %s -> %s\n", src_file_path, dst_file_path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user