This patch adds the --copy-devices option, which will try to copy
the data inside a device instead of duplicating the device node.
To use this patch, run these commands for a successful build:
patch -p1 <patches/copy-devices.diff
./prepare-source
./configure (optional if already run)
make
based-on: e94bad1c156fc3910f24e2b3b71a81b0b0bdeb70
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
@@ -39,6 +39,7 @@ extern int preserve_acls;
extern int preserve_xattrs;
extern int preserve_links;
extern int preserve_devices;
+extern int copy_devices;
extern int write_devices;
extern int preserve_specials;
extern int preserve_hard_links;
@@ -1679,7 +1680,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
- if (!S_ISREG(file->mode)) {
+ if (!(S_ISREG(file->mode) || (copy_devices && IS_DEVICE(file->mode)))) {
if (solo_file)
fname = f_name(file, NULL);
rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
@@ -1900,6 +1901,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fnamecmp_type = FNAMECMP_BACKUP;
}
+ if (IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0)
+ sx.st.st_size = get_device_size(fd, fnamecmp);
+
if (DEBUG_GTE(DELTASUM, 3)) {
rprintf(FINFO, "gen mapped %s of size %s\n",
fnamecmp, big_num(sx.st.st_size));
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
@@ -47,6 +47,7 @@ int append_mode = 0;
int keep_dirlinks = 0;
int copy_dirlinks = 0;
int copy_links = 0;
+int copy_devices = 0;
int write_devices = 0;
int preserve_links = 0;
int preserve_hard_links = 0;
@@ -652,6 +653,7 @@ static struct poptOption long_options[] = {
{"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 },
+ {"copy-devices", 0, POPT_ARG_NONE, ©_devices, 0, 0, 0 },
{"write-devices", 0, POPT_ARG_VAL, &write_devices, 1, 0, 0 },
{"no-write-devices", 0, POPT_ARG_VAL, &write_devices, 0, 0, 0 },
{"specials", 0, POPT_ARG_VAL, &preserve_specials, 1, 0, 0 },
@@ -942,6 +944,7 @@ static void set_refuse_options(void)
|| strcmp("iconv", longName) == 0
|| strcmp("no-iconv", longName) == 0
|| strcmp("checksum-seed", longName) == 0
+ || strcmp("copy-devices", longName) == 0 /* disable wild-match (it gets refused below) */
|| strcmp("write-devices", longName) == 0 /* disable wild-match (it gets refused below) */
|| strcmp("log-format", longName) == 0 /* aka out-format (NOT log-file-format) */
|| strcmp("sender", longName) == 0
@@ -953,6 +956,7 @@ static void set_refuse_options(void)
assert(list_end != NULL);
if (am_daemon) { /* Refused by default, but can be accepted via a negated exact match. */
+ parse_one_refuse_match(0, "copy-devices", list_end);
parse_one_refuse_match(0, "write-devices", list_end);
}
@@ -2895,6 +2899,9 @@ void server_options(char **args, int *argc_p)
else if (remove_source_files)
args[ac++] = "--remove-sent-files";
+ if (copy_devices)
+ args[ac++] = "--copy-devices";
+
if (preallocate_files && am_sender)
args[ac++] = "--preallocate";
diff --git a/rsync.1.md b/rsync.1.md
--- a/rsync.1.md
+++ b/rsync.1.md
@@ -368,6 +368,7 @@ detailed description below for a complete description.
--owner, -o preserve owner (super-user only)
--group, -g preserve group
--devices preserve device files (super-user only)
+--copy-devices copy device contents as regular file
--specials preserve special files
-D same as --devices --specials
--times, -t preserve modification times
diff --git a/rsync.c b/rsync.c
--- a/rsync.c
+++ b/rsync.c
@@ -33,6 +33,7 @@ extern int preserve_xattrs;
extern int preserve_perms;
extern int preserve_executability;
extern int preserve_times;
+extern int copy_devices;
extern int am_root;
extern int am_server;
extern int am_daemon;
@@ -419,7 +420,8 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr, cha
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) || (copy_devices && IS_DEVICE(file->mode)))) {
rprintf(FERROR,
"received request to transfer non-regular file: %d [%s]\n",
ndx, who_am_i());
diff --git a/rsyncd.conf.5.md b/rsyncd.conf.5.md
--- a/rsyncd.conf.5.md
+++ b/rsyncd.conf.5.md
@@ -930,9 +930,10 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
If you are un-refusing the compress option, you probably want to match
"`!compress*`" so that you also accept the `--compress-level` option.
- Note that the "write-devices" option is refused by default, but can be
- explicitly accepted with "`!write-devices`". The options "log-file" and
- "log-file-format" are forcibly refused and cannot be accepted.
+ Note that the "copy-devices" & "write-devices" options are refused by
+ default, but they can be explicitly accepted with "`!copy-devices`" and/or
+ "`!write-devices`". The options "log-file" and "log-file-format" are
+ forcibly refused and cannot be accepted.
Here are all the options that are not matched by wild-cards:
diff --git a/sender.c b/sender.c
--- a/sender.c
+++ b/sender.c
@@ -362,6 +362,9 @@ void send_files(int f_in, int f_out)
exit_cleanup(RERR_FILEIO);
}
+ if (IS_DEVICE(st.st_mode) && st.st_size == 0)
+ st.st_size = get_device_size(fd, fname);
+
if (st.st_size) {
int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE);
mbuf = map_file(fd, st.st_size, read_size, s->blength);
diff -Nurp a/rsync.1 b/rsync.1
--- a/rsync.1
+++ b/rsync.1
@@ -444,6 +444,7 @@ detailed description below for a complet
--owner, -o preserve owner (super-user only)
--group, -g preserve group
--devices preserve device files (super-user only)
+--copy-devices copy device contents as regular file
--specials preserve special files
-D same as --devices --specials
--times, -t preserve modification times
diff -Nurp a/rsync.1.html b/rsync.1.html
--- a/rsync.1.html
+++ b/rsync.1.html
@@ -359,6 +359,7 @@ detailed description below for a complet
--owner, -o preserve owner (super-user only)
--group, -g preserve group
--devices preserve device files (super-user only)
+--copy-devices copy device contents as regular file
--specials preserve special files
-D same as --devices --specials
--times, -t preserve modification times
diff -Nurp a/rsyncd.conf.5 b/rsyncd.conf.5
--- a/rsyncd.conf.5
+++ b/rsyncd.conf.5
@@ -918,9 +918,10 @@ option.
If you are un-refusing the compress option, you probably want to match
"\fB!compress*\fP" so that you also accept the \fB\-\-compress-level\fP option.
.IP
-Note that the "write-devices" option is refused by default, but can be
-explicitly accepted with "\fB!write-devices\fP". The options "log-file" and
-"log-file-format" are forcibly refused and cannot be accepted.
+Note that the "copy-devices" & "write-devices" options are refused by
+default, but they can be explicitly accepted with "\fB!copy-devices\fP" and/or
+"\fB!write-devices\fP". The options "log-file" and "log-file-format" are
+forcibly refused and cannot be accepted.
.IP
Here are all the options that are not matched by wild-cards:
.IP
diff -Nurp a/rsyncd.conf.5.html b/rsyncd.conf.5.html
--- a/rsyncd.conf.5.html
+++ b/rsyncd.conf.5.html
@@ -895,9 +895,10 @@ instead of returning an error that force
option.</p>
<p>If you are un-refusing the compress option, you probably want to match
"<code>!compress*</code>" so that you also accept the <code>--compress-level</code> option.</p>
-<p>Note that the "write-devices" option is refused by default, but can be
-explicitly accepted with "<code>!write-devices</code>". The options "log-file" and
-"log-file-format" are forcibly refused and cannot be accepted.</p>
+<p>Note that the "copy-devices" & "write-devices" options are refused by
+default, but they can be explicitly accepted with "<code>!copy-devices</code>" and/or
+"<code>!write-devices</code>". The options "log-file" and "log-file-format" are
+forcibly refused and cannot be accepted.</p>
<p>Here are all the options that are not matched by wild-cards:</p>
<ul>
<li><code>--server</code>: Required for rsync to even work.</li>
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>