Unable to copy the shared library's soft links with their original size in linux - linux

I have created a shared object of 1.2 M and created 4 soft links for that SO.
Size of all the links is 20B and the size of the main so is 1.2M
20 May 23 10:56 libAbc.so -> libAbc.so.2.0.11.0
20 May 23 10:56 libAbc.so.1 -> libAbc.so.2.0.11.0
20 May 23 10:56 libAbc.so.1.0 -> libAbc.so.2.0.11.0
1.2M May 23 10:56 libAbc.so.2.0.11.0
While i tried to copy all these files to another folder using cp , the size of the links is equal to the main file.
1.2M May 24 08:07 libABC.so
1.2M May 24 08:07 libABC.so.1
1.2M May 24 08:07 libABC.so.1.0
1.2M May 24 08:07 libABC.so.2.0.11.0
I have also used
cp -s libAgent.so* src/
which is also failing with an error
cp: `src/libAgent.so': can make relative symbolic links only in current directory
Why is it failing to copy the softlinks with their original size(20B)

Copying a soft link usually copies the file the soft link refers to and does not replicate the soft link.
If you wish to use cp to copy soft links as new soft links, specify the -a option to cp.
cp -a libAbc.so* /path/to/another/folder
The info page for cp says:
`-a'
`--archive'
Preserve as much as possible of the structure and attributes of the
original files in the copy (but do not attempt to preserve internal
directory structure; i.e., `ls -U' may list the entries in a copied
directory in a different order). Equivalent to `-dpR'.
The key is to select the "archive" option of the command used to copy the link. rsync is an effective alternative as Maxim Egorushkin points out, and rsync has the capability of copying extended attributes and ACLs if the command includes the appropriate command-line arguments.
rsync -aAX libAbc.so* /path/to/another/folder
The rsync man page says:
-a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)
--no-OPTION turn off an implied OPTION (e.g. --no-D)
-A, --acls preserve ACLs (implies -p)
-X, --xattrs preserve extended attributes
In the OP's use case, the -A and -X are not needed.
A caveat is that if the soft link is a relative link, copying it to a new location may make the link inoperative because it does not point to an absolute path.
For example:
$ ls -al /usr/lib/rpmpopt
lrwxrwxrwx 1 root root 19 2012-05-02 12:40 /usr/lib/rpmpopt -> rpm/rpmpopt-4.4.2.3
cp -a /usr/lib/rpmpopt ${HOME}/tmp and rsync -av /usr/lib/rpmpopt ${HOME}/tmp on my machine both create a broken link rpmpopt -> rpm/rpmpopt-4.4.2.3 because my local copy has no rpm sub-folder. One needs to consider this fact when deciding what to copy.
This link is broken because ${HOME}/tmp/rpm is not present:
$ ls -nl ${HOME}/tmp/rpmpopt
lrwxrwxrwx 1 505 700 19 2016-05-24 10:04 /home/kbulgrien/tmp/rpmpopt -> rpm/rpmpopt-4.4.2.3

rsync is less error-prone then cp:
rsync -av libAgent.so* src/

Related

How to use rsync properly to keep all file permissions and ownership?

I am trying to use rsync to backup some data from one computer (PopOS! 21.04) to another (Rocky 8.4). But no matter which flags I use with rsync, file permissions and ownership never seem to be saved.
What I do, is run this command locally on PopOS:
sudo rsync -avz /home/user1/test/ root#192.168.10.11:/root/ttt/
And the result I get something link this:
[root#rocky_clone0 ~]# ls -ld ttt/
drwxrwxr-x. 2 user23 user23 32 Dec 17 2021 ttt/
[root#rocky_clone0 ~]# ls -l ttt/
total 8
-rw-rw-r--. 1 user23 user23 57 Dec 17 2021 test1
-rw-rw-r--. 1 user23 user23 29 Dec 17 2021 test2
So all the file ownership change to user23, which is the only regular user on Rocky. I don't understand how this happens, with rsync I am connecting to root on the remote host, but as the result files are copied as user23. Why isn't -a flag work properly in this case?
I have also tried these flags:
sudo rsync -avz --rsync-path="sudo -u user23 rsync -a" /home/user1/test root#192.168.10.11:/home/user23/rrr
This command couldn't copy to the root directory, so I had to change the remote destination to user23's home folder. But the result is the same.
If someone could explain to me what am I doing wrong, and how to backup files with rsync so that permissions and ownership stay the same as on the local computer I would very much appreciate it.
Have a look at how the (target)filesystem is mounted on the Rocky(target) system.
Some mounted filesystems (such as many FUSE mounts) do not support the classical unix permissions, and simply use the name of the user who mounted the filesystem as owner/group.
Any attempt to chown/chmod/etc (either by you or by rsync) will just silently be ignored, but appear to "succeed" (no errors reported).

cp command to handle empty directories (resulting in diff file sizes)

I am trying to copy directories (& files) recursively from one directory to another.
I tried the following -
rsync -avz <source> <target>
cp -ruT <source> <taret>
Both were successful. but, when i try to compare the sizes using (du -c), the empty directories seem to have mismatch in size.
In target directory
drwxrwxr-x 2 abc devl 4096 Jun 9 01:25 .
drwxrwxr-x 4 abc devl 4096 Jul 20 07:46 ..
In source directory
drwxrwxr-x 2 prod ops 2 Jun 9 01:25 .
drwxrwxr-x 4 prod ops 36 Jul 20 07:46 ..
Is there a special way to handle this? diff -qr doesn't show any differences though.
Thanks for your help.
Are both folders on the same volume? If not chances are that the sector size for those volumes are different and in turn the inode sizes differ. In case of diff it's just looking at whenever or not the directory exists and if it contains the corresponding files. It's similar in how diff doesn't include permission differences because those might be pretty system specific.
A pretty comprehensive answer can be found here: Why size reporting for directories is different than other files?

Can cygwin ls show ACLs without providing the DOS path to file?

The commands
cd c:/p4
ls -ld . c:/p4 /cygdrive/c/p4
shows
d---------+ 1 jgunter Domain Users 0 Apr 27 18:41 .
d---------+ 1 jgunter Domain Users ? 0 Apr 27 18:41 /cygdrive/c/p4
drwxr-xr-x 1 jgunter Domain Users ? 0 Apr 27 18:41 c:/p4
ls shows the perms I want to see only for files specified with a C:/ path.
I know about getfacl, but I'm hoping there's some ls option that will show me what I want without requiring I spell out absolute paths.
I can do something like:
ls -ld `cygpath -da $#`
but when I'm in a deeply nested folder, the output is cluttered by full pathnames.
DOS path makes cygwin treat the file system as not having ACLs. It means that ls shows the correct ACLs, but the same directory is mounted with different options. Therefore ls doesn't have such an option, you need a workaround.
https://cygwin.com/cygwin-ug-net/ov-new1.7.html states at 1.7.2:
Handle native DOS paths always as if mounted with "posix=0,noacl"
Beside this, I think, that d---------+ is strange. I've tried it on my PC, with 1.7.31 cygwin version, and it shows drwx------+, which is a bit better. I had experienced other bugs and strange behaviour in cygwin ACL handling. I guess there is confusion and some hacks about this. chmod 777 was a good workaround in my case.

mv command not working as intended on linux CENT/REDHAT OS

This is with respect to recent issue that has been faced by me. Suddenly post exection of a mv command Linux box went un-responsive on various front, below is the overall description of the issue that happened.
1) move command executed with /* in the destination
# mv -f *.txt /*
2) command has successfully moved the desired content but not to / it moved it to /var
3) along with desired content it also moved content of / folders recursivly to /var location.
4) this resulted in movement of all binary files and folders required for normal OS operations
5) this movement restricted login through SSH/console.
6) post restoration of folders from /var location system got functions normally.
I tried replicating the issue on test Linux Box and it got replicated as below,
[root#TestVM001 ~]# ls -lrt
total 84
-rw-r--r-- 1 root root 4224 Feb 5 17:28 install.log.syslog
-rw-r--r-- 1 root root 38536 Feb 5 17:35 install.log
-rw------- 1 root root 955 Feb 5 17:35 anaconda-ks.cfg
drwxr-xr-x 2 root root 4096 Feb 5 20:03 Desktop
-rw-r--r-- 1 root root 119 Feb 5 20:28 ifcfg-eth0
-rw-r--r-- 1 root root 119 Feb 6 15:17 ifcfg-eth1
-rw-r--r-- 1 root root 44 Mar 1 05:08 student.txt
drwxr-xr-x 3 root root 4096 Mar 14 17:59 admin
[root#TestVM001 ~]# mv -vf * /*
`admin' -> `/var/admin'
`anaconda-ks.cfg' -> `/var/anaconda-ks.cfg'
`Desktop' -> `/var/Desktop'
`ifcfg-eth0' -> `/var/ifcfg-eth0'
`ifcfg-eth1' -> `/var/ifcfg-eth1'
`install.log' -> `/var/install.log'
`install.log.syslog' -> `/var/install.log.syslog'
`student.txt' -> `/var/student.txt'
`/bin' -> `/var/bin'
mv: cannot move `/boot' to `/var/boot': Device or resource busy
mv: cannot move `/dev' to `/var/dev': Device or resource busy
`/etc' -> `/var/etc'
`/home' -> `/var/home'
mv: cannot move `/lib' to a subdirectory of itself, `/var/lib'
`/lost+found' -> `/var/lost+found'
`/media' -> `/var/media'
`/mnt' -> `/var/mnt'
`/opt' -> `/var/opt'
mv: cannot move `/proc' to `/var/proc': Device or resource busy
`/root' -> `/var/root'
`/sbin' -> `/var/sbin'
`/selinux' -> `/var/selinux'
`/srv' -> `/var/srv'
mv: cannot move `/sys' to `/var/sys': Device or resource busy
`/tmp' -> `/var/tmp'
`/usr' -> `/var/usr'
[root#TestVM001 ~]# ls
-bash: /bin/ls: No such file or directory
[root#TestVM001 ~]# ls -lrt
-bash: /bin/ls: No such file or directory
[root#TestVM001 ~]# cd /
.autofsck boot/ lib/ sys/
.autorelabel dev/ proc/ var/
[root#TestVM001 ~]# cd /var/
account/ games/ lost+found/ selinux/
admin/ gdm/ mail/ spool/
anaconda-ks.cfg home/ media/ srv/
bin/ ifcfg-eth0 mnt/ student.txt
cache/ ifcfg-eth1 nis/ tmp/
crash/ install.log opt/ tux/
cvs/ install.log.syslog preserve/ usr/
db/ lib/ racoon/ www/
Desktop/ local/ root/ yp/
empty/ lock/ run/
etc/ log/ sbin/
Questions about this scenarios is,
1) Why mv command resulted in such behavior?
2) Is this behavior is a known Bug or Risk?
3) IS there any known way to restrict this, similar to alias concept usage?
When you do echo mv -f *.txt /* you will see that the last * has been expanded to /var. So you actually asked to move all files in / to /var.
The answers to your questions:
1) Why mv command resulted in such behavior?
mv tried to do exactly what you asked
2) Is this behavior is a known Bug or Risk?
It's not a bug. Unix/Linux do not have prompts "are you sure" but trust the you.
3) IS there any known way to restrict this, similar to alias concept usage?
You should do all normal work as a plain user, not root. The permissions on the important files are such, that they do not allow a normal user to do something harmful.
And when you must do something as root, be very careful!
Trying to move txt files to the root is suspicious: The root partition is small and should be kept for system files. Are the .txt files from Windows?

What is there behind a symbolic link?

How are symbolic links managed internally by UNIX/Linux systems. It is known that a symbolic link may exist even without an actual target file (Dangling link). So what is that which represents a symbolic link internally.
In Windows, the answer is a reparse point.
Questions:
Is the answer an inode in UNIX/Linux?
If yes, then will the inode number be same for target and links?
If yes, can the link inode can have permissions different from that of target's inode (if one exists)?
It is not about UNIX/Linux but about filesystem implementation - but yes, Unix/Linux uses inodes at kernel level and filesystem implementations have inodes (at least virtual ones).
In the general, symbolic links are simply files (btw, directories are also files), that have:
the flag file-type in the "inode" that tells to the system this file is a "symbolic link"
file-content: path to the target - in other words: a symbolic link is simply a file which contains a filename with a flag in the inode.
Virtual filesystems can have symbolic links too, so, check FUSE or some other filesystem implementation sources. (ext2/ext3/ufs..etc)
So,
Is the answer an inode in UNIX/Linux?
depends on filesystem implementation, but yes, generally the inode contains a "file-type" (and owners, access rights, timestamps, size, pointers to data blocks). There are filesystems that don't have inodes (in a physical implementation) but have only "virtual inodes" for maintaining compatibility with the kernel.
If yes, then will the inode number be same for target and links?
No. Usually, the symlink is a file with its own inode, (with file-type, own data blocks, etc.)
If yes, can the link inode can have permissions different from that of target's
inode(if one exists)?
This is about how symlink files are handled. Usually, the kernel doesn't allow changes to the symlink permissions - and symlinks always have default permissions. You could write your own filesystem that would allow different permissions for symlinks, but you would get into trouble because common programs like chmod don't change permissions on symlinks themselves, so making such a filesystem would be pointless anyway)
To understand the difference between hard links and symlinks, you should understand directories first.
Directories are files (with differentiated by a flag in the inode) that tell the kernel, "handle this file as a map of file-name to inode_number". Hard-links are simply file names that map to the same inode. So if the directory-file contains:
file_a: 1000
file_b: 1001
file_c: 1000
the above means, in this directory, are 3 files:
file_a described by inode 1000
file_b described by inode 1001 and
file_c again described by inode 1000 (so it is a hard link with file_a, not hardlink to file_a - because it is impossible to tell which filename came first - they are identical).
This is the main difference to symlinks, where the inode of file_b (inode 1001) could have content "file_a" and a flag meaning "this is a symlink". In this case, file_b would be a symlink pointing to file_a.
You can also easily explore this on your own:
$ touch a
$ ln -s a b
$ ln a c
$ ls -li
total 0
95905 -rw-r--r-- 1 regnarg regnarg 0 Jun 19 19:01 a
96990 lrwxrwxrwx 1 regnarg regnarg 1 Jun 19 19:01 b -> a
95905 -rw-r--r-- 2 regnarg regnarg 0 Jun 19 19:01 c
The -i option to ls shows inode numbers in the first column. You can see that the symlink has a different inode number while the hardlink has the same. You can also use the stat(1) command:
$ stat a
File: 'a'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 28h/40d Inode: 95905 Links: 2
[...]
$ stat b
File: 'b' -> 'a'
Size: 1 Blocks: 0 IO Block: 4096 symbolic link
Device: 28h/40d Inode: 96990 Links: 1
[...]
If you want to do this programmatically, you can use the lstat(2) system call to find information about the symlink itself (its inode number etc.), while stat(2) shows information about the target of the symlink, if it exists. Example in Python:
>>> import os
>>> os.stat("b").st_ino
95905
>>> os.lstat("b").st_ino
96990

Resources