summaryrefslogtreecommitdiff
path: root/src/file.h
blob: 883cb326ed783e8e6ae25d4f7382fd418761ec35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#ifndef _FILE_H_
#define _FILE_H_

#include <limits.h>
#include <pthread.h>
#include "libssh/libssh.h"
#include "libssh/sftp.h"

#include <list.h>
#include <atomic.h>

struct file {
	struct list_head        list;   /* mscp->file_list */

	char    src_path[PATH_MAX];	/* copy source path */
	bool    src_is_remote;		/* source is remote */
	size_t  size;			/* size of this file */

	char    dst_path[PATH_MAX];	/* copy destination path */
	bool    dst_is_remote;		/* destination is remote */

	int     state;  /* destination file state */
	lock    lock;   /* mutex to protect state */
	refcnt  refcnt; /* chunks referencing this file */
};
#define FILE_STATE_INIT         0
#define FILE_STATE_OPENED       1
#define FILE_STATE_DONE         2

#define strloc(is_remote) is_remote ? "(remote)" : "(local)"

/* Allocating chunk increments refcnt of the associating file.
 * Multiple threads copying files follows:
 *
 * acquire a chunk (inside a global lock)
 *
 * if the file state of the chunk is INIT:
 *     acquire the file lock
 * *         if file state is INIT:
 *             create directory if necessary
 *             open file with O_TRUNC and close.
 *             set file state OPENED.
 *             // only the first thread in the lock open the destination file
 *     release the file lock
 * endif
 *
 * copy the chunk to the destination.
 * decrement the refcnt of the file.
 *
 * if refcnt == 0:
 *     all chunks are copied.
 *     set the file state DONE, print something useful output.
 * endif
 */

struct chunk {
	struct list_head        list;   /* mscp->chunk_list */
	struct file *f;
	size_t  off;    /* offset of this chunk on the file f */
	size_t  len;    /* length of this chunk */
	size_t  done;   /* copied bytes for this chunk by a thread */
};

char *file_find_hostname(char *path);
bool file_has_hostname(char *path);

int file_fill(sftp_session sftp, struct list_head *file_list, char **src_array, int cnt,
	      char *dst);

int chunk_fill(struct list_head *file_list, struct list_head *chunk_list,
	       int nr_conn, int min_chunk_sz, int max_chunk_sz);

struct chunk *chunk_acquire(struct list_head *chunk_list);
int chunk_prepare(struct chunk *c, sftp_session sftp);
int chunk_copy(struct chunk *c, sftp_session sftp, size_t sftp_buf_sz, size_t io_buf_sz,
	       int nr_ahead, size_t *counter);

#ifdef DEBUG
void file_dump(struct list_head *file_list);
void chunk_dump(struct list_head *chunk_list);
#endif


#endif /* _FILE_H_ */