1 This patch adds the --copy-devices option, which will try to copy
2 the data inside a device instead of duplicating the device node.
4 To use this patch, run these commands for a successful build:
6 patch -p1 <patches/copy-devices.diff
8 ./configure (optional if already run)
11 based-on: 194cee671d5e178f20c4494f41911fa8db942935
12 diff --git a/generator.c b/generator.c
15 @@ -39,6 +39,7 @@ extern int preserve_acls;
16 extern int preserve_xattrs;
17 extern int preserve_links;
18 extern int preserve_devices;
19 +extern int copy_devices;
20 extern int write_devices;
21 extern int preserve_specials;
22 extern int preserve_hard_links;
23 @@ -1650,7 +1651,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
27 - if (!S_ISREG(file->mode)) {
28 + if (!(S_ISREG(file->mode) || (copy_devices && IS_DEVICE(file->mode)))) {
30 fname = f_name(file, NULL);
31 rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
32 @@ -1871,6 +1872,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
33 fnamecmp_type = FNAMECMP_BACKUP;
36 + if (IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0)
37 + sx.st.st_size = get_device_size(fd, fnamecmp);
39 if (DEBUG_GTE(DELTASUM, 3)) {
40 rprintf(FINFO, "gen mapped %s of size %s\n",
41 fnamecmp, big_num(sx.st.st_size));
42 diff --git a/options.c b/options.c
45 @@ -51,6 +51,7 @@ int append_mode = 0;
46 int keep_dirlinks = 0;
47 int copy_dirlinks = 0;
49 +int copy_devices = 0;
50 int write_devices = 0;
51 int preserve_links = 0;
52 int preserve_hard_links = 0;
53 @@ -851,6 +852,7 @@ static struct poptOption long_options[] = {
54 {"no-D", 0, POPT_ARG_NONE, 0, OPT_NO_D, 0, 0 },
55 {"devices", 0, POPT_ARG_VAL, &preserve_devices, 1, 0, 0 },
56 {"no-devices", 0, POPT_ARG_VAL, &preserve_devices, 0, 0, 0 },
57 + {"copy-devices", 0, POPT_ARG_NONE, ©_devices, 0, 0, 0 },
58 {"write-devices", 0, POPT_ARG_VAL, &write_devices, 1, 0, 0 },
59 {"no-write-devices", 0, POPT_ARG_VAL, &write_devices, 0, 0, 0 },
60 {"specials", 0, POPT_ARG_VAL, &preserve_specials, 1, 0, 0 },
61 @@ -1148,6 +1150,7 @@ static void set_refuse_options(void)
62 || strcmp("iconv", longName) == 0
63 || strcmp("no-iconv", longName) == 0
64 || strcmp("checksum-seed", longName) == 0
65 + || strcmp("copy-devices", longName) == 0 /* disable wild-match (it gets refused below) */
66 || strcmp("write-devices", longName) == 0 /* disable wild-match (it gets refused below) */
67 || strcmp("log-format", longName) == 0 /* aka out-format (NOT log-file-format) */
68 || strcmp("sender", longName) == 0
69 @@ -1159,6 +1162,7 @@ static void set_refuse_options(void)
70 assert(list_end != NULL);
72 if (am_daemon) { /* Refused by default, but can be accepted via a negated exact match. */
73 + parse_one_refuse_match(0, "copy-devices", list_end);
74 parse_one_refuse_match(0, "write-devices", list_end);
77 @@ -2890,6 +2894,9 @@ void server_options(char **args, int *argc_p)
78 else if (remove_source_files)
79 args[ac++] = "--remove-sent-files";
82 + args[ac++] = "--copy-devices";
84 if (preallocate_files && am_sender)
85 args[ac++] = "--preallocate";
87 diff --git a/rsync.1.md b/rsync.1.md
90 @@ -367,6 +367,7 @@ detailed description below for a complete description.
91 --owner, -o preserve owner (super-user only)
92 --group, -g preserve group
93 --devices preserve device files (super-user only)
94 +--copy-devices copy device contents as regular file
95 --specials preserve special files
96 -D same as --devices --specials
97 --times, -t preserve modification times
98 diff --git a/rsync.c b/rsync.c
101 @@ -33,6 +33,7 @@ extern int preserve_xattrs;
102 extern int preserve_perms;
103 extern int preserve_executability;
104 extern int preserve_times;
105 +extern int copy_devices;
107 extern int am_server;
108 extern int am_daemon;
109 @@ -419,7 +420,8 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr, cha
111 if (iflags & ITEM_TRANSFER) {
112 int i = ndx - cur_flist->ndx_start;
113 - if (i < 0 || !S_ISREG(cur_flist->files[i]->mode)) {
114 + struct file_struct *file = cur_flist->files[i];
115 + if (i < 0 || !(S_ISREG(file->mode) || (copy_devices && IS_DEVICE(file->mode)))) {
117 "received request to transfer non-regular file: %d [%s]\n",
119 diff --git a/rsyncd.conf.5.md b/rsyncd.conf.5.md
120 --- a/rsyncd.conf.5.md
121 +++ b/rsyncd.conf.5.md
122 @@ -913,9 +913,10 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
123 If you are un-refusing the compress option, you probably want to match
124 "`!compress*`" so that you also accept the `--compress-level` option.
126 - Note that the "write-devices" option is refused by default, but can be
127 - explicitly accepted with "`!write-devices`". The options "log-file" and
128 - "log-file-format" are forcibly refused and cannot be accepted.
129 + Note that the "copy-devices" & "write-devices" options are refused by
130 + default, but they can be explicitly accepted with "`!copy-devices`" and/or
131 + "`!write-devices`". The options "log-file" and "log-file-format" are
132 + forcibly refused and cannot be accepted.
134 Here are all the options that are not matched by wild-cards:
136 diff --git a/sender.c b/sender.c
139 @@ -362,6 +362,9 @@ void send_files(int f_in, int f_out)
140 exit_cleanup(RERR_FILEIO);
143 + if (IS_DEVICE(st.st_mode) && st.st_size == 0)
144 + st.st_size = get_device_size(fd, fname);
147 int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE);
148 mbuf = map_file(fd, st.st_size, read_size, s->blength);