Hi Denis Corbin!
On 2011.02.28 at 21:02:46 +0100, Denis Corbin wrote next:
> Simple: it ignores link count for directory inodes (dar 2.4.0 support
> hard links for plain files (like dar 2.3.x), char and block devices
> (new), named pipes (new), symlinks (new) but not for directories).
> For other type of inode than directories, if the link count is 1, it
> assumes a normal entry (not subject to hard linking), else it assumes
> that the inode may be subject to a hard link and checks if its number
> (and filesystem ID) is not already present in the mapping table, in
> which case it records a hard link for that entry in the catalogue else
> adds this inode number in a mapping table.
Guys, I'm truly sorry for confusion. Thing is, I was confused myself;
reading strange shell script that created that second proc in chroot
messed up my mind.
First of all, it was not hardlink, but indeed a mount. Second, it wasn't
bind mount; thing is, special filesystems sys and proc are allowed to be
mounted as many time as needed, therefore it's common for chroot to have
them mounted there. It's not a bind mount, rather just second mount -
which is perfectly allowed for proc, being virtual filesystem and all.
It's not displayed by mount because it's not in /etc/mtab. There are
such filesystems; for example, try this on modern linux system
$ grep bus/usb /proc/mounts
/proc/bus/usb /proc/bus/usb usbfs rw,relatime 0 0
now try to find that mount in "mount" output :)
this example demonstrates second proc which won't be in mount output
# mkdir p
# mount -n proc p -t proc
As for how to deal with this. I have a suggestion but it requires work,
i.e. actually code some stuff, which you obviously might not like.. I'm
not sure how much code is needed to implement this in dar design, even
:-/ However I think it's a very powerful feature which can be useful for
lots of occasions in dar. However I don't even know if it's possible to
implement this easily with dar filesystem/filter layers separation, even
if code for this feature should be pretty simple.
Thing is, you can detect such mounts (actually, I discovered this as a
portable way to detecting door solaris files, yes it's this
universal..), stat utility does it:
# stat -f /var/named/chroot/proc
ID: 0 Namelen: 255 Type: proc
Block size: 4096 Fundamental block size: 4096
Blocks: Total: 0 Free: 0 Available: 0
Inodes: Total: 0 Free: 0
example of door:
$ stat -f /etc/dev/.devfsadm_synch_door
ID: 8640000 Namelen: 0 Type: namefs
Block size: 1024 Fundamental block size: 1024
Blocks: Total: 0 Free: 0 Available: 0
Inodes: Total: 0 Free: 0
Anyhow the feature I propose - a new option to dar, list of filesystems
It's used like this:
It creates list of string of filesystems to exclude.
Implemented like this - real code will be quite a bit more complicated,
just to show how it works:
fd = current file descriptor;
fstatvfs(int fd, &fs_info)
if (fs_info.f_basetype in list of filesystems to exclude)
if fd = file
elif fd = directory
if (-D option)
put empty dir into backup
don't descend into subdirs, move to next target
Having such feature will automatically allow dar to skip all proc-type
fs which it meets, sysfs (/sys), network filesystems and such, without
specifying exact locations, behaviour would be exactly as if it's
excluded with -P and directory will be stored if -D option is specified
(or, maybe, it always should store directory for such autoskips,
regardless of -D). I believe it's easier and safer way than using -P
option to exclude network & virtual filesystems, also it automatically
will adopt better to various operating systems, like
solaris/linux/freebsd with just a few "excludefs" options, without
specifying any paths which can be different for these filesystems.
Good example of filesystems which aren't to be backed up is in
updatedb.conf in my distribution, which catches lots of virtual
filesystems, network filesystems, filesystems mounted in ram, mounted
cd/dvd images and such:
PRUNEFS = "9p afs anon_inodefs auto autofs bdev binfmt_misc cgroup cifs
coda configfs cpuset debugfs devpts ecryptfs exofs fuse fusectl gfs gfs2
hugetlbfs inotifyfs iso9660 jffs2 lustre mqueue ncpfs nfs nfs4 pipefs
proc ramfs rootfs rpc_pipefs securityfs selinuxfs sfs sockfs sysfs tmpfs
ubifs udf usbfs"
While such feature will automatically skip files of door type ("namefs"
on solaris), it's not really the best option to work around them, but
that's another matter, and a small detail.
Now, the problem. It seems complicated to actually get that filesystem
name, sadly. I read
http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/stat.c code, and
here is the problem: while statvfs/fstatvfs have f_basename field with
null-terminated string containing filesystem name
(char f_basetype[FSTYPSZ], where FSTYPESZ equals 16), some other systems
do not. stat.c has quite complicated code for this; in fact, it states
/* Return the type of the specified file system.
Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, and Solaris).
Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0).
Others have statfs.f_fstypename[MFSNAMELEN] (NetBSD 1.5.2).
Still others have neither and have to get by with f_type (GNU/Linux).
But f_type may only exist in statfs (Cygwin). */
It has definitions like
#if (STAT_STATVFS \
&& (HAVE_STRUCT_STATVFS_F_BASETYPE || HAVE_STRUCT_STATVFS_F_FSTYPENAME \
|| (! HAVE_STRUCT_STATFS_F_FSTYPENAME && HAVE_STRUCT_STATVFS_F_TYPE)))
# define USE_STATVFS 1
# define USE_STATVFS 0
# include <sys/statvfs.h>
# include <sys/vfs.h>
#elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H
/* NOTE: freebsd5.0 needs sys/param.h and sys/mount.h for statfs.
It does have statvfs.h, but shouldn't use it, since it doesn't
HAVE_STRUCT_STATVFS_F_BASETYPE. So find a clean way to fix it. */
/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */
# include <sys/param.h>
# include <sys/mount.h>
# if HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H
/* Ultrix 4.4 needs these for the declaration of struct statfs. */
# include <netinet/in.h>
# include <nfs/nfs_clnt.h>
# include <nfs/vfs.h>
#elif HAVE_OS_H /* BeOS */
# include <fs_info.h>
and comments like
/* BeOS has a statvfs function, but it does not return sensible values
for f_files, f_ffree and f_favail, and lacks f_type, f_basetype and
f_fstypename. Use 'struct fs_info' instead. */
In other words, there is no 100% portable and simple code to do this.
Linux can only give uint constant for filesystem type, which must be
then parsed by code like
case S_MAGIC_ADFS: /* 0xADF5 */
case S_MAGIC_AFFS: /* 0xADFF */
case S_MAGIC_AFS: /* 0x5346414F */
case S_MAGIC_ANON_INODE_FS: /* 0x09041934 */
return "anon-inode FS";
Well here I can help. If you are interested in this feature, I can
implement portable (but complicated!) filesystem detection, based on
stat.c code. I will have to use coreutils 6.9 code which is GPLv2+ (6.10
and on are GPLv3+), but this shouldn't really matter, doubt there are
any changes to this program.
In other words, I will provide you with some function which returns
string with filesystem name for selected file descriptor (or path).
However, writing integration of this feature into dar - providing new
option, arguments parsing, structure for storing multiple fs names to
exclude and actually comparing, be that
strncmp(mystring, yourstring, 16) or some more high level function to
compare with your list of strings, and acting depending on match will be
up to you. Though, I really think all this code will be rather simple,
if it's possible to implement this in dar design right now; only
complicated stuff will be function to get filesystem name, i.e. its
I might also need your help with defining autoconf macros for detecting
OS features on this function, if I won't find that code in coreutils,
and function that I write will be probably in pure C, which I'm far more
familiar with than C++. Self-test of such function should be easy, just
parsing /proc/mounts and testing functions against complicated examples
from there on a few systems should be good enough.
Are you interested? I really believe that such feature can solve quite
a few shortcomings with current way of keeping virtual & network
filesystems away from dar's touch.