-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lack of IO error checks generate incorrect file checksums #215
Comments
@spbooth --- <unnamed>
+++ <unnamed>
@@ -28,8 +28,11 @@
int i;
int fd;
int n;
+ ssize_t readlen;
globus_off_t count;
globus_off_t read_left;
+ struct stat statbuf;
+ int is_regular;
rc = globus_url_parse_loose(url, &parsed_url);
if(rc != 0)
@@ -80,8 +83,10 @@
parsed_url.url_path));
goto error_fd;
}
+ fstat(fd,&statbuf);
+ is_regular = S_ISREG(statbuf.st_mode);
- if (lseek(fd, offset, SEEK_SET) == -1)
+ if (is_regular && lseek(fd, offset, SEEK_SET) == -1)
{
result = globus_error_put(
globus_error_construct_string(
@@ -123,15 +128,26 @@
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
- while((n = read(fd, buf, count)) > 0)
+ if( is_regular )
{
- if(length >= 0)
+ while((n = (readlen = read(fd, buf, count))) > 0)
{
- read_left -= n;
- count = (read_left > GASS_COPY_CKSM_BUFSIZE) ? GASS_COPY_CKSM_BUFSIZE : read_left;
+ if(length >= 0)
+ {
+ read_left -= n;
+ count = (read_left > GASS_COPY_CKSM_BUFSIZE) ? GASS_COPY_CKSM_BUFSIZE : read_left;
+ }
+
+ EVP_DigestUpdate(mdctx, buf, n);
}
-
- EVP_DigestUpdate(mdctx, buf, n);
+ if( readlen < 0 && count > 0 ){
+ result = globus_error_put(globus_error_construct_string(
+ GLOBUS_GASS_COPY_MODULE,
+ GLOBUS_NULL,
+ "Read error in checksum calculation url=%s read_left =%d %d %s",
+ url,read_left,readlen, strerror(errno)));
+ goto error_seek;
+ }
}
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
@@ -149,7 +165,7 @@
*cksmptr = '\0';
strncpy(cksm, cksm_buff, sizeof(cksm_buff));
-
+ //globus_libc_fprintf(stderr,"SPB file-checksum %s=%s\n",url,cksm);
globus_url_destroy(&parsed_url);
if(callback)
Would you maybe like to also provide a pull request for this change so we can run it through our CI and do a complete review? And BTW, is this part of the "sync" functionality of |
Its definately part of -verify-checksum. It might also be part of -sync I'll make a pull request soon. Might be worth re-writing the checksum to use buffered io as well it might speed up the checksum phase and would be more consistent with the rest of the file. |
Looks like our documentation over at https://gridcf.org/gct-docs/ is incomplete in this regard, at least the following two
Looking forward to that.
Might be a good idea, though at least for non-parallel MD5 I recently only got up to 483 MiB/s for a file on a Lustre FS. This is already limiting for 10 Gbps. What they developed on https://dzone.com/articles/parallelizing-md5-checksum-computation-to-speed-up looks more promising. |
Ive submitted a pull request. In the end I stayes with unbuffered io as the checksum buffer is pretty big anyway but I switched to the gass stat function to keep the code portable |
The routine globus_l_gass_copy_cksm_file() in globus_gass_copy_glob.c
has a file read loop
while((n = read(fd,buf,count)) > 0)
If an IO error occurs in the read call it will return -1 and the loop will terminate early generating an incorrect digest for the file but no error report until the subsequent file transfer fails its checksum test.
On a related note if you check for errors properly you discover that a recursive globus-url-copy attempts to calculate checksums on directory-urls using this routine (which always generates a error in the read call)
My POC fix is
But it probably needs a bit of tidying up.
The text was updated successfully, but these errors were encountered: