mirror of
https://github.com/upa/mscp.git
synced 2026-03-12 02:57:34 +08:00
use pseudo glob/globfree for remote-glob when musl
musllibc does not implement GLOB_ALTDIRFUNC, so do not call glob for remote sides when libc is musl. test_e2e.py skips test_glob_src_path when running on alpine.
This commit is contained in:
@@ -128,7 +128,7 @@ struct dirent *mscp_readdir(MDIR *md)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(&tls_dirent, 0, sizeof(tls_dirent));
|
memset(&tls_dirent, 0, sizeof(tls_dirent));
|
||||||
strlcpy(tls_dirent.d_name, attr->name, sizeof(tls_dirent.d_name));
|
strncpy(tls_dirent.d_name, attr->name, sizeof(tls_dirent.d_name) - 1);
|
||||||
tls_dirent.d_ino = inum++;
|
tls_dirent.d_ino = inum++;
|
||||||
if (!inum)
|
if (!inum)
|
||||||
inum = 1;
|
inum = 1;
|
||||||
@@ -306,28 +306,54 @@ int mscp_chmod(const char *path, mode_t mode, sftp_session sftp)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int errfunc(const char *epath, int err)
|
|
||||||
{
|
|
||||||
printf("errfunc for path %s\n", epath);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mscp_glob(const char *pattern, int flags, glob_t *pglob, sftp_session sftp)
|
int mscp_glob(const char *pattern, int flags, glob_t *pglob, sftp_session sftp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
if (sftp) {
|
if (sftp) {
|
||||||
|
#ifndef GLOB_ALTDIRFUNC
|
||||||
|
#define GLOB_NOALTDIRMAGIC INT_MAX
|
||||||
|
/* musl does not implement GLOB_ALTDIRFUNC */
|
||||||
|
pglob->gl_pathc = 1;
|
||||||
|
pglob->gl_pathv = malloc(sizeof(char *));
|
||||||
|
pglob->gl_pathv[0] = strdup(pattern);
|
||||||
|
pglob->gl_offs = GLOB_NOALTDIRMAGIC;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
flags |= GLOB_ALTDIRFUNC;
|
||||||
|
set_tls_sftp_session(sftp);
|
||||||
|
#ifdef __APPLE__
|
||||||
pglob->gl_opendir = (void *(*)(const char *))mscp_opendir_wrapped;
|
pglob->gl_opendir = (void *(*)(const char *))mscp_opendir_wrapped;
|
||||||
pglob->gl_readdir = (struct dirent *(*)(void *))mscp_readdir;
|
pglob->gl_readdir = (struct dirent *(*)(void *))mscp_readdir;
|
||||||
pglob->gl_closedir = (void (*)(void *))mscp_closedir;
|
pglob->gl_closedir = (void (*)(void *))mscp_closedir;
|
||||||
pglob->gl_lstat = mscp_lstat_wrapped;
|
pglob->gl_lstat = mscp_lstat_wrapped;
|
||||||
pglob->gl_stat = mscp_stat_wrapped;
|
pglob->gl_stat = mscp_stat_wrapped;
|
||||||
flags |= GLOB_ALTDIRFUNC;
|
#elif linux
|
||||||
set_tls_sftp_session(sftp);
|
pglob->gl_opendir = (void *(*)(const char *))mscp_opendir_wrapped;
|
||||||
|
pglob->gl_readdir = (void *(*)(void *))mscp_readdir;
|
||||||
|
pglob->gl_closedir = (void (*)(void *))mscp_closedir;
|
||||||
|
pglob->gl_lstat = (int (*)(const char *, void *))mscp_lstat_wrapped;
|
||||||
|
pglob->gl_stat = (int (*)(const char *, void *))mscp_stat_wrapped;
|
||||||
|
#else
|
||||||
|
#error unsupported platform
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = glob(pattern, flags, errfunc, pglob);
|
ret = glob(pattern, flags, NULL, pglob);
|
||||||
|
|
||||||
if (sftp)
|
if (sftp)
|
||||||
set_tls_sftp_session(NULL);
|
set_tls_sftp_session(NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mscp_globfree(glob_t *pglob)
|
||||||
|
{
|
||||||
|
#ifndef GLOB_ALTDIRFUNC
|
||||||
|
if (pglob->gl_offs == GLOB_NOALTDIRMAGIC) {
|
||||||
|
free(pglob->gl_pathv[0]);
|
||||||
|
free(pglob->gl_pathv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
globfree(pglob);
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,3 +50,4 @@ int mscp_chmod(const char *path, mode_t mode, sftp_session sftp);
|
|||||||
|
|
||||||
/* remote glob */
|
/* remote glob */
|
||||||
int mscp_glob(const char *pattern, int flags, glob_t *pglob, sftp_session sftp);
|
int mscp_glob(const char *pattern, int flags, glob_t *pglob, sftp_session sftp);
|
||||||
|
void mscp_globfree(glob_t *pglob);
|
||||||
|
|||||||
@@ -446,7 +446,7 @@ void *mscp_scan_thread(void *arg)
|
|||||||
|
|
||||||
list_splice_tail(&tmp, m->path_list.prev);
|
list_splice_tail(&tmp, m->path_list.prev);
|
||||||
}
|
}
|
||||||
globfree(&pglob);
|
mscp_globfree(&pglob);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpr_info(m->msg_fp, "walk source path(s) done\n");
|
mpr_info(m->msg_fp, "walk source path(s) done\n");
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ param_single_copy = [
|
|||||||
@pytest.mark.parametrize("src, dst", param_single_copy)
|
@pytest.mark.parametrize("src, dst", param_single_copy)
|
||||||
def test_single_copy(mscp, src_prefix, dst_prefix, src, dst):
|
def test_single_copy(mscp, src_prefix, dst_prefix, src, dst):
|
||||||
src.make()
|
src.make()
|
||||||
run2ok([mscp, "-H", src_prefix + src.path, dst_prefix + dst.path])
|
run2ok([mscp, "-H", "-vvv", src_prefix + src.path, dst_prefix + dst.path])
|
||||||
assert check_same_md5sum(src, dst)
|
assert check_same_md5sum(src, dst)
|
||||||
src.cleanup()
|
src.cleanup()
|
||||||
dst.cleanup()
|
dst.cleanup()
|
||||||
@@ -65,7 +65,7 @@ def test_single_copy(mscp, src_prefix, dst_prefix, src, dst):
|
|||||||
def test_failed_to_copy_nonexistent_file(mscp, src_prefix, dst_prefix):
|
def test_failed_to_copy_nonexistent_file(mscp, src_prefix, dst_prefix):
|
||||||
src = "nonexistent_src"
|
src = "nonexistent_src"
|
||||||
dst = "nonexistent_dst"
|
dst = "nonexistent_dst"
|
||||||
run2ng([mscp, "-H", src_prefix + src, dst_prefix + dst])
|
run2ng([mscp, "-H", "-vvv", src_prefix + src, dst_prefix + dst])
|
||||||
|
|
||||||
param_double_copy = [
|
param_double_copy = [
|
||||||
(File("src1", size = 1024 * 1024), File("src2", size = 1024 * 1024),
|
(File("src1", size = 1024 * 1024), File("src2", size = 1024 * 1024),
|
||||||
@@ -77,7 +77,7 @@ param_double_copy = [
|
|||||||
def test_double_copy(mscp, src_prefix, dst_prefix, s1, s2, d1, d2):
|
def test_double_copy(mscp, src_prefix, dst_prefix, s1, s2, d1, d2):
|
||||||
s1.make()
|
s1.make()
|
||||||
s2.make()
|
s2.make()
|
||||||
run2ok([mscp, "-H", src_prefix + s1.path, src_prefix + s2.path, dst_prefix + "dst"])
|
run2ok([mscp, "-H", "-vvv", src_prefix + s1.path, src_prefix + s2.path, dst_prefix + "dst"])
|
||||||
assert check_same_md5sum(s1, d1)
|
assert check_same_md5sum(s1, d1)
|
||||||
assert check_same_md5sum(s2, d2)
|
assert check_same_md5sum(s2, d2)
|
||||||
s1.cleanup()
|
s1.cleanup()
|
||||||
@@ -114,11 +114,11 @@ def test_dir_copy(mscp, src_prefix, dst_prefix, src_dir, dst_dir, src, dst, twic
|
|||||||
for f in src:
|
for f in src:
|
||||||
f.make()
|
f.make()
|
||||||
|
|
||||||
run2ok([mscp, "-H", src_prefix + src_dir, dst_prefix + dst_dir])
|
run2ok([mscp, "-H", "-vvv", src_prefix + src_dir, dst_prefix + dst_dir])
|
||||||
for sf, df in zip(src, dst):
|
for sf, df in zip(src, dst):
|
||||||
assert check_same_md5sum(sf, df)
|
assert check_same_md5sum(sf, df)
|
||||||
|
|
||||||
run2ok([mscp, "-H", src_prefix + src_dir, dst_prefix + dst_dir])
|
run2ok([mscp, "-H", "-vvv", src_prefix + src_dir, dst_prefix + dst_dir])
|
||||||
for sf, df in zip(src, twice):
|
for sf, df in zip(src, twice):
|
||||||
assert check_same_md5sum(sf, df)
|
assert check_same_md5sum(sf, df)
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ def test_override_single_file(mscp, src_prefix, dst_prefix):
|
|||||||
dst = File("dst", size = 128).make()
|
dst = File("dst", size = 128).make()
|
||||||
assert not check_same_md5sum(src, dst)
|
assert not check_same_md5sum(src, dst)
|
||||||
|
|
||||||
run2ok([mscp, "-H", src_prefix + src.path, dst_prefix + dst.path])
|
run2ok([mscp, "-H", "-vvv", src_prefix + src.path, dst_prefix + dst.path])
|
||||||
assert check_same_md5sum(src, dst)
|
assert check_same_md5sum(src, dst)
|
||||||
|
|
||||||
src.cleanup()
|
src.cleanup()
|
||||||
@@ -144,13 +144,21 @@ def test_min_chunk(mscp, src_prefix, dst_prefix):
|
|||||||
src = File("src", size = 16 * 1024).make()
|
src = File("src", size = 16 * 1024).make()
|
||||||
dst = File("dst")
|
dst = File("dst")
|
||||||
|
|
||||||
run2ok([mscp, "-H", "-s", 32768, src_prefix + src.path, dst_prefix + dst.path])
|
run2ok([mscp, "-H", "-vvv", "-s", 32768, src_prefix + src.path, dst_prefix + dst.path])
|
||||||
assert check_same_md5sum(src, dst)
|
assert check_same_md5sum(src, dst)
|
||||||
|
|
||||||
src.cleanup()
|
src.cleanup()
|
||||||
dst.cleanup()
|
dst.cleanup()
|
||||||
|
|
||||||
|
|
||||||
|
def is_alpine():
|
||||||
|
if os.path.exists("/etc/os-release"):
|
||||||
|
with open("/etc/os-release", "r") as f:
|
||||||
|
for line in f:
|
||||||
|
if line.strip() == "ID=alpine":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
param_glob_copy = [
|
param_glob_copy = [
|
||||||
(
|
(
|
||||||
"src*", "dstx",
|
"src*", "dstx",
|
||||||
@@ -164,6 +172,8 @@ param_glob_copy = [
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@pytest.mark.skipif(is_alpine(),
|
||||||
|
reason = "musl does not implement glob ALTDIRFUNC")
|
||||||
@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
|
@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
|
||||||
@pytest.mark.parametrize("src_glob_path, dst_path, srcs, dsts", param_glob_copy)
|
@pytest.mark.parametrize("src_glob_path, dst_path, srcs, dsts", param_glob_copy)
|
||||||
def test_glob_src_path(mscp, src_prefix, dst_prefix,
|
def test_glob_src_path(mscp, src_prefix, dst_prefix,
|
||||||
@@ -182,7 +192,7 @@ def test_thread_affinity(mscp, src_prefix, dst_prefix):
|
|||||||
src = File("src", size = 64 * 1024).make()
|
src = File("src", size = 64 * 1024).make()
|
||||||
dst = File("dst")
|
dst = File("dst")
|
||||||
|
|
||||||
run2ok([mscp, "-H", "-n", 4, "-m", "0x01",
|
run2ok([mscp, "-H", "-vvv", "-n", 4, "-m", "0x01",
|
||||||
src_prefix + src.path, dst_prefix + dst.path])
|
src_prefix + src.path, dst_prefix + dst.path])
|
||||||
assert check_same_md5sum(src, dst)
|
assert check_same_md5sum(src, dst)
|
||||||
|
|
||||||
@@ -194,7 +204,7 @@ def test_cannot_override_file_with_dir(mscp, src_prefix, dst_prefix):
|
|||||||
src = File("src", size = 128).make()
|
src = File("src", size = 128).make()
|
||||||
dst = File("dst").make()
|
dst = File("dst").make()
|
||||||
|
|
||||||
run2ng([mscp, "-H", src_prefix + src.path, dst_prefix + "dst/src"])
|
run2ng([mscp, "-H", "-vvv", src_prefix + src.path, dst_prefix + "dst/src"])
|
||||||
|
|
||||||
src.cleanup()
|
src.cleanup()
|
||||||
dst.cleanup()
|
dst.cleanup()
|
||||||
@@ -203,7 +213,7 @@ def test_cannot_override_file_with_dir(mscp, src_prefix, dst_prefix):
|
|||||||
def test_transfer_zero_bytes(mscp, src_prefix, dst_prefix):
|
def test_transfer_zero_bytes(mscp, src_prefix, dst_prefix):
|
||||||
src = File("src", size = 0).make()
|
src = File("src", size = 0).make()
|
||||||
dst = File("dst")
|
dst = File("dst")
|
||||||
run2ok([mscp, "-H", src_prefix + src.path, dst_prefix + "dst"])
|
run2ok([mscp, "-H", "-vvv", src_prefix + src.path, dst_prefix + "dst"])
|
||||||
assert os.path.exists("dst")
|
assert os.path.exists("dst")
|
||||||
src.cleanup()
|
src.cleanup()
|
||||||
dst.cleanup()
|
dst.cleanup()
|
||||||
@@ -212,7 +222,7 @@ def test_transfer_zero_bytes(mscp, src_prefix, dst_prefix):
|
|||||||
def test_override_dst_having_larger_size(mscp, src_prefix, dst_prefix):
|
def test_override_dst_having_larger_size(mscp, src_prefix, dst_prefix):
|
||||||
src = File("src", size = 1024 * 1024).make()
|
src = File("src", size = 1024 * 1024).make()
|
||||||
dst = File("dst", size = 1024 * 1024 * 2).make()
|
dst = File("dst", size = 1024 * 1024 * 2).make()
|
||||||
run2ok([mscp, "-H", src_prefix + src.path, dst_prefix + "dst"])
|
run2ok([mscp, "-H", "-vvv", src_prefix + src.path, dst_prefix + "dst"])
|
||||||
assert check_same_md5sum(src, dst)
|
assert check_same_md5sum(src, dst)
|
||||||
src.cleanup()
|
src.cleanup()
|
||||||
dst.cleanup()
|
dst.cleanup()
|
||||||
@@ -223,7 +233,7 @@ compressions = ["yes", "no", "none"]
|
|||||||
def test_compression(mscp, src_prefix, dst_prefix, compress):
|
def test_compression(mscp, src_prefix, dst_prefix, compress):
|
||||||
src = File("src", size = 1024 * 1024).make()
|
src = File("src", size = 1024 * 1024).make()
|
||||||
dst = File("dst", size = 1024 * 1024 * 2).make()
|
dst = File("dst", size = 1024 * 1024 * 2).make()
|
||||||
run2ok([mscp, "-H", "-C", compress, src_prefix + src.path, dst_prefix + "dst"])
|
run2ok([mscp, "-H", "-vvv", "-C", compress, src_prefix + src.path, dst_prefix + "dst"])
|
||||||
assert check_same_md5sum(src, dst)
|
assert check_same_md5sum(src, dst)
|
||||||
src.cleanup()
|
src.cleanup()
|
||||||
dst.cleanup()
|
dst.cleanup()
|
||||||
|
|||||||
Reference in New Issue
Block a user