ALT Linux Bugzilla
– Attachment 4646 Details for
Bug 24497
add new option: --rw-devices
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
[patch]
"притёртый" патч
rw-devices.alt.diff (text/plain), 11.80 KB, created by
ildar
on 2010-11-04 10:48:21 MSK
(
hide
)
Description:
"притёртый" патч
Filename:
MIME Type:
Creator:
ildar
Created:
2010-11-04 10:48:21 MSK
Size:
11.80 KB
patch
obsolete
>diff -ru rsync-c31e3fd/flist.c rsync-c31e3fd.NEW/flist.c >--- rsync-c31e3fd/flist.c 2010-03-24 22:10:36.000000000 +0600 >+++ rsync-c31e3fd.NEW/flist.c 2010-11-04 12:41:15.586451965 +0600 >@@ -63,6 +63,7 @@ > extern int prune_empty_dirs; > extern int copy_links; > extern int copy_unsafe_links; >+extern int rw_devices; > extern int protocol_version; > extern int sanitize_paths; > extern int munge_symlinks; >@@ -216,7 +217,7 @@ > #endif > } > >-int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks) >+static int link_stat2(const char *path, STRUCT_STAT *stp, int follow_dirlinks) > { > #ifdef SUPPORT_LINKS > if (copy_links) >@@ -234,6 +235,28 @@ > #endif > } > >+int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks) >+{ >+ if (link_stat2(path, stp, follow_dirlinks) != 0) >+ return -1; >+ if (rw_devices && S_ISBLK(stp->st_mode) && stp->st_size == 0) { >+ /* On Linux systems (at least), st_size is typically 0 for devices. >+ * If so, try to determine the actual device size. */ >+ int fdx = do_open(path, O_RDONLY, 0); >+ if (fdx == -1) >+ rsyserr(FERROR, errno, "failed to open device %s to determine size", path); >+ else { >+ OFF_T off = lseek(fdx, 0, SEEK_END); >+ if (off == (OFF_T)-1) >+ rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", path); >+ else >+ stp->st_size = off; >+ close(fdx); >+ } >+ } >+ return 0; >+} >+ > static inline int is_daemon_excluded(const char *fname, int is_dir) > { > if (daemon_filter_list.head >@@ -626,7 +649,7 @@ > the_end: > strlcpy(lastname, fname, MAXPATHLEN); > >- if (S_ISREG(mode) || S_ISLNK(mode)) >+ if (S_ISREG(mode) || S_ISLNK(mode) || (rw_devices && S_ISBLK(mode))) > stats.total_size += F_LENGTH(file); > } > >@@ -1269,7 +1292,8 @@ > #ifdef HAVE_STRUCT_STAT_ST_RDEV > if (IS_DEVICE(st.st_mode)) { > tmp_rdev = st.st_rdev; >- st.st_size = 0; >+ if (!rw_devices || !S_ISBLK(st.st_mode)) >+ st.st_size = 0; > } else if (IS_SPECIAL(st.st_mode)) > st.st_size = 0; > #endif >diff -ru rsync-c31e3fd/generator.c rsync-c31e3fd.NEW/generator.c >--- rsync-c31e3fd/generator.c 2010-03-24 22:10:36.000000000 +0600 >+++ rsync-c31e3fd.NEW/generator.c 2010-11-04 12:49:55.007459516 +0600 >@@ -39,6 +39,7 @@ > extern int preserve_xattrs; > extern int preserve_links; > extern int preserve_devices; >+extern int rw_devices; > extern int preserve_specials; > extern int preserve_hard_links; > extern int preserve_executability; >@@ -1367,6 +1368,23 @@ > > statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir); > stat_errno = errno; >+ >+ if (statret == 0 && IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0) { >+ /* On Linux systems (at least), st_size is typically 0 for devices. >+ * If so, try to determine the actual device size. */ >+ int fdx = do_open(fname, O_RDONLY, 0); >+ if ( fdx == -1 ) { >+ rsyserr(FERROR, errno, "failed to open device %s to determine size", fname); >+ } >+ else { >+ OFF_T off = lseek(fdx, 0, SEEK_END); >+ if (off == (OFF_T)-1) >+ rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname); >+ else >+ sx.st.st_size = off; >+ close(fdx); >+ } >+ } > } > > if (ignore_non_existing > 0 && statret == -1 && stat_errno == ENOENT) { >@@ -1695,7 +1713,7 @@ > goto cleanup; > } > >- if (!S_ISREG(file->mode)) { >+ if (!(S_ISREG(file->mode) || (rw_devices && IS_DEVICE(file->mode)))) { > if (solo_file) > fname = f_name(file, NULL); > rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname); >@@ -1733,7 +1751,7 @@ > fnamecmp = fname; > fnamecmp_type = FNAMECMP_FNAME; > >- if (statret == 0 && !S_ISREG(sx.st.st_mode)) { >+ if (statret == 0 && !(S_ISREG(sx.st.st_mode) || (rw_devices && IS_DEVICE(sx.st.st_mode)))) { > if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0) > goto cleanup; > statret = -1; >diff -ru rsync-c31e3fd/options.c rsync-c31e3fd.NEW/options.c >--- rsync-c31e3fd/options.c 2010-03-24 22:10:36.000000000 +0600 >+++ rsync-c31e3fd.NEW/options.c 2010-11-04 11:26:25.530476061 +0600 >@@ -48,6 +48,7 @@ > int keep_dirlinks = 0; > int copy_dirlinks = 0; > int copy_links = 0; >+int rw_devices = 0; > int preserve_links = 0; > int preserve_hard_links = 0; > int preserve_acls = 0; >@@ -351,6 +352,7 @@ > rprintf(F," -o, --owner preserve owner (super-user only)\n"); > rprintf(F," -g, --group preserve group\n"); > rprintf(F," --devices preserve device files (super-user only)\n"); >+ rprintf(F," --rw-devices read/write device contents as regular file (implies --inplace)\n"); > rprintf(F," --specials preserve special files\n"); > rprintf(F," -D same as --devices --specials\n"); > rprintf(F," -t, --times preserve modification times\n"); >@@ -509,6 +511,7 @@ > {"no-D", 0, POPT_ARG_NONE, 0, OPT_NO_D, 0, 0 }, > {"devices", 0, POPT_ARG_VAL, &preserve_devices, 1, 0, 0 }, > {"no-devices", 0, POPT_ARG_VAL, &preserve_devices, 0, 0, 0 }, >+ {"rw-devices", 0, POPT_ARG_NONE, &rw_devices, 0, 0, 0 }, > {"specials", 0, POPT_ARG_VAL, &preserve_specials, 1, 0, 0 }, > {"no-specials", 0, POPT_ARG_VAL, &preserve_specials, 0, 0, 0 }, > {"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 }, >@@ -1284,6 +1287,11 @@ > exit_cleanup(0); > } > >+ if (rw_devices) { >+ inplace = 1; >+ ignore_times = 1; >+ } >+ > #ifdef ICONV_OPTION > if (iconv_opt && protect_args != 2) { > if (!am_server && strcmp(iconv_opt, "-") == 0) >@@ -2072,6 +2080,9 @@ > else if (remove_source_files) > args[ac++] = "--remove-sent-files"; > >+ if (rw_devices) >+ args[ac++] = "--rw-devices"; >+ > if (ac > MAX_SERVER_ARGS) { /* Not possible... */ > rprintf(FERROR, "argc overflow in server_options().\n"); > exit_cleanup(RERR_MALLOC); >diff -ru rsync-c31e3fd/receiver.c rsync-c31e3fd.NEW/receiver.c >--- rsync-c31e3fd/receiver.c 2010-03-24 22:10:36.000000000 +0600 >+++ rsync-c31e3fd.NEW/receiver.c 2010-11-04 12:48:10.727437968 +0600 >@@ -38,6 +38,7 @@ > extern int relative_paths; > extern int preserve_hard_links; > extern int preserve_perms; >+extern int rw_devices; > extern int preserve_xattrs; > extern int basis_dir_cnt; > extern int make_backups; >@@ -166,6 +167,7 @@ > static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r, > const char *fname, int fd, OFF_T total_size) > { >+ STRUCT_STAT st; > static char file_sum1[MAX_DIGEST_LEN]; > static char file_sum2[MAX_DIGEST_LEN]; > struct map_struct *mapbuf; >@@ -286,10 +288,14 @@ > goto report_write_error; > > #ifdef HAVE_FTRUNCATE >- if (inplace && fd != -1 >- && ftruncate(fd, offset) < 0) { >- rsyserr(FERROR_XFER, errno, "ftruncate failed on %s", >- full_fname(fname)); >+ (void)do_fstat(fd,&st); >+ /* Makes no sense to attempt to ftruncate() a block device: */ >+ if (!(IS_DEVICE(st.st_mode))) { >+ if (inplace && fd != -1 >+ && ftruncate(fd, offset) < 0) { >+ rsyserr(FERROR_XFER, errno, "ftruncate failed on %s", >+ full_fname(fname)); >+ } > } > #endif > >@@ -669,11 +675,25 @@ > continue; > } > >- if (fd1 != -1 && !S_ISREG(st.st_mode)) { >+ if (fd1 != -1 && !(S_ISREG(st.st_mode) || (rw_devices && IS_DEVICE(st.st_mode)))) { > close(fd1); > fd1 = -1; > } > >+ /* On Linux systems (at least), st_size is typically 0 for devices. >+ * If so, try to determine the actual device size. */ >+ if (fd1 != -1 && IS_DEVICE(st.st_mode) && st.st_size == 0) { >+ OFF_T off = lseek(fd1, 0, SEEK_END); >+ if (off == (OFF_T) -1) >+ rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname); >+ else { >+ st.st_size = off; >+ off = lseek(fd1, 0, SEEK_SET); >+ if (off != 0) >+ rsyserr(FERROR, errno, "failed to seek back to beginning of %s to read it", fname); >+ } >+ } >+ > /* If we're not preserving permissions, change the file-list's > * mode based on the local permissions and some heuristics. */ > if (!preserve_perms) { >diff -ru rsync-c31e3fd/rsync.c rsync-c31e3fd.NEW/rsync.c >--- rsync-c31e3fd/rsync.c 2010-03-24 22:10:36.000000000 +0600 >+++ rsync-c31e3fd.NEW/rsync.c 2010-11-04 12:21:48.743434343 +0600 >@@ -34,6 +34,7 @@ > extern int preserve_perms; > extern int preserve_executability; > extern int preserve_times; >+extern int rw_devices; > extern int am_root; > extern int am_server; > extern int am_sender; >@@ -328,7 +329,8 @@ > > if (iflags & ITEM_TRANSFER) { > int i = ndx - cur_flist->ndx_start; >- if (i < 0 || !S_ISREG(cur_flist->files[i]->mode)) { >+ struct file_struct *file = cur_flist->files[i]; >+ if (i < 0 || !(S_ISREG(file->mode) || (rw_devices && IS_DEVICE(file->mode)))) { > rprintf(FERROR, > "received request to transfer non-regular file: %d [%s]\n", > ndx, who_am_i()); >diff -ru rsync-c31e3fd/syscall.c rsync-c31e3fd.NEW/syscall.c >--- rsync-c31e3fd/syscall.c 2010-03-24 22:10:36.000000000 +0600 >+++ rsync-c31e3fd.NEW/syscall.c 2010-11-04 12:26:30.418460351 +0600 >@@ -35,6 +35,7 @@ > extern int list_only; > extern int preserve_perms; > extern int preserve_executability; >+extern int rw_devices; > > #define RETURN_ERROR_IF(x,e) \ > do { \ >@@ -241,20 +242,56 @@ > int do_stat(const char *fname, STRUCT_STAT *st) > { > #ifdef USE_STAT64_FUNCS >- return stat64(fname, st); >+ if (stat64(fname, st) != 0) >+ return -1; > #else >- return stat(fname, st); >+ if (stat(fname, st) != 0) >+ return -1; > #endif >+ if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) { >+ /* On Linux systems (at least), st_size is typically 0 for devices. >+ * If so, try to determine the actual device size. */ >+ int fdx = do_open(fname, O_RDONLY, 0); >+ if (fdx == -1) >+ rsyserr(FERROR, errno, "failed to open device %s to determine size", fname); >+ else { >+ OFF_T off = lseek(fdx, 0, SEEK_END); >+ if (off == (OFF_T)-1) >+ rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname); >+ else >+ st->st_size = off; >+ close(fdx); >+ } >+ } >+ return 0; > } > > int do_lstat(const char *fname, STRUCT_STAT *st) > { > #ifdef SUPPORT_LINKS > # ifdef USE_STAT64_FUNCS >- return lstat64(fname, st); >+ if (lstat64(fname, st) != 0) >+ return -1; > # else >- return lstat(fname, st); >+ if (lstat(fname, st) != 0) >+ return -1; > # endif >+ if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) { >+ /* On Linux systems (at least), st_size is typically 0 for devices. >+ * If so, try to determine the actual device size. */ >+ int fdx = do_open(fname, O_RDONLY, 0); >+ if (fdx == -1) >+ rsyserr(FERROR, errno, "failed to open device %s to determine size", fname); >+ else { >+ OFF_T off = lseek(fdx, 0, SEEK_END); >+ if (off == (OFF_T)-1) >+ rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname); >+ else >+ st->st_size = off; >+ close(fdx); >+ } >+ } >+ return 0; > #else > return do_stat(fname, st); > #endif >@@ -263,10 +300,30 @@ > int do_fstat(int fd, STRUCT_STAT *st) > { > #ifdef USE_STAT64_FUNCS >- return fstat64(fd, st); >+ if (fstat64(fd, st) != 0) >+ return -1; > #else >- return fstat(fd, st); >+ if (fstat(fd, st) != 0) >+ return -1; > #endif >+ if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) { >+ /* On Linux systems (at least), st_size is typically 0 for devices. >+ * If so, try to determine the actual device size. */ >+ OFF_T off_save = lseek(fd, 0, SEEK_CUR); >+ if (off_save == (OFF_T)-1) >+ rsyserr(FERROR, errno, "failed to seek on device inode %lld to read current position", (long long int)(st->st_ino)); >+ else { >+ OFF_T off = lseek(fd, 0, SEEK_END); >+ if (off == (OFF_T)-1) >+ rsyserr(FERROR, errno, "failed to seek to end on device inode %lld to determine size", (long long int)(st->st_ino)); >+ else >+ st->st_size = off; >+ off = lseek(fd, off_save, SEEK_SET); >+ if (off == (OFF_T)-1) >+ rsyserr(FERROR, errno, "failed to seek to origin position on device inode %lld", (long long int)(st->st_ino)); >+ } >+ } >+ return 0; > } > > OFF_T do_lseek(int fd, OFF_T offset, int whence)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 24497
:
4645
| 4646