First off /sys
is a pseudo file system. If you look at /proc/filesystems
you will find a list of registered file systems where quite a few has nodev
in front. This indicates they are pseudo filesystems. This means they exists
on a running kernel as a RAM-based filesystem. Further they do not require a
block device.
$ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev bdev
...
At boot the kernel mount this system and updates entries when suited. E.g. when
new hardware is found during boot or by udev
.
In /etc/mtab
you typically find the mount by:
sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
For a nice paper on the subject read
Patric Mochel's – The sysfs Filesystem.
stat of /sys files
If you go into a directory under /sys
and do a ls -l
you will notice that
all files has one size. Typically 4096 bytes. This is reported by sysfs
.
:/sys/devices/pci0000:00/0000:00:19.0/net/eth2$ ls -l
-r--r--r-- 1 root root 4096 Apr 24 20:09 addr_assign_type
-r--r--r-- 1 root root 4096 Apr 24 20:09 address
-r--r--r-- 1 root root 4096 Apr 24 20:09 addr_len
...
Further you can do a stat
on a file and notice another distinct feature;
it occupies 0 blocks. Also inode of root (stat /sys) is 1. /stat/fs
typically
has inode 2. etc.
rsync vs. cp
The easiest explanation for rsync failure of synchronizing pseudo files is
perhaps by example.
Say we have a file named address
that is 18 bytes. An ls
or stat
of the
file reports 4096 bytes.
rsync
- Opens file descriptor, fd.
- Uses fstat(fd) to get information such as size.
- Set out to read size bytes, i.e. 4096. That would be line 253 of the code linked by @mattdm.
read_size == 4096
- Ask; read: 4096 bytes.
- A short string is read i.e. 18 bytes.
nread == 18
read_size = read_size - nread (4096 - 18 = 4078)
- Ask; read: 4078 bytes
- 0 bytes read (as first read consumed all bytes in file).
nread == 0
, line 255
- Unable to read
4096
bytes. Zero out buffer.
- Set error
ENODATA
.
- Return.
- Report error.
- Retry. (Above loop).
- Fail.
- Report error.
- FINE.
During this process it actually reads the entire file. But with no size
available it cannot validate the result – thus failure is only option.
cp
- Opens file descriptor, fd.
- Uses fstat(fd) to get information such as st_size (also uses lstat and stat).
Check if file is likely to be sparse. That is the file has holes etc.
copy.c:1010
/* Use a heuristic to determine whether SRC_NAME contains any sparse
* blocks. If the file has fewer blocks than would normally be
* needed for a file of its size, then at least one of the blocks in
* the file is a hole. */
sparse_src = is_probably_sparse (&src_open_sb);
As stat
reports file to have zero blocks it is categorized as sparse.
Tries to read file by extent-copy (a more efficient way to copy normal
sparse files), and fails.
- Copy by sparse-copy.
- Starts out with max read size of MAXINT.
Typically
18446744073709551615
bytes on a 32 bit system.
- Ask; read 4096 bytes. (Buffer size allocated in memory from stat information.)
- A short string is read i.e. 18 bytes.
- Check if a hole is needed, nope.
- Write buffer to target.
- Subtract 18 from max read size.
- Ask; read 4096 bytes.
- 0 bytes as all got consumed in first read.
- Return success.
- All OK. Update flags for file.
- FINE.
/sys/
? – frostschutz Apr 24 '13 at 16:38/sys/class/net/*/address
(I get "permission denied" when I try it)? If not, then you aren't making a real/useful backup since it can't be restored. – depquid Apr 24 '13 at 21:11