How do I remove a possible hard-link directory to root?

3

I know hard links to directories aren't supposed to be possible but it I have something odd on my NAS that looks very much like one. This folder originally came from a linux machine and appears to have come from dfm. At some point in time it was backed up onto an NTFS-formatted USB drive which was then transferred to a Synology NAS.

dwj$ ls -la
drwx------  1 dwj  staff  16384 Mar  2 19:17 .linktorootdir

dwj$ ls -la .linktorootdir/
total 3460
drwx------  1 shennis  staff    16384 Mar  2 19:17 .
drwx------  1 shennis  staff    16384 Jul 25 23:29 ..
drwx------  1 shennis  staff    16384 Feb 26 20:20 .system_info
drwx------  1 shennis  staff    16384 Feb 26 20:20 bin
drwx------  1 shennis  staff    16384 Mar  2 19:15 dev
drwx------  1 shennis  staff    16384 Mar  2 19:17 etc.defaults
-rwx------  1 shennis  staff  1589952 Dec 11  2012 linuxrc
drwx------  1 shennis  staff    16384 Feb 26 20:20 sbin
drwx------  1 shennis  staff    16384 Mar  2 04:49 tmp
drwx------  1 shennis  staff    16384 Mar  2 19:17 usr
drwx------  1 shennis  staff    16384 Mar  2 19:17 volume1
drwx------  1 shennis  staff    16384 Mar  1 21:44 volumeUSB2

Output of pwd; stat .linktorootdir; mount

DiskStation> pwd

/volume1/usbcopy/USBCopy_1303012145

DiskStation> ls -a

.                       .linktorootdir
..                      Data
.DS_Store

DiskStation> stat -f .linktorootdir/ /

  File: ".linktorootdir/"
    ID: 1a03a45c0ea41689 Namelen: 255     Type: ext2/ext3
Block size: 4096
Blocks: Total: 719905408  Free: 654479     Available: 628879
Inodes: Total: 182845440  Free: 180250664

  File: "/"
    ID: 6a3b023a9a57044b Namelen: 255     Type: ext2/ext3
Block size: 4096
Blocks: Total: 612766     Free: 503152     Available: 477552
Inodes: Total: 155648     Free: 139669

DiskStation> mount

/dev/root on / type ext4 (rw,relatime,barrier=0,journal_checksum,data=ordered)
/tmp on /tmp type tmpfs (0) none on /dev/pts type devpts (gid=4,mode=620) /sys on
/sys type sysfs (0) /proc/bus/usb on /proc/bus/usb type usbfs (0)
/dev/vg1000/lv on /volume1 type ext4 (usrjquota=aquota.user,grpjquota=aquota.gro up,jqfmt=vfsv0,synoacl)

Checking inodes (per recommendation by @pabouk) with ls -lai / ; ls -lai /volume1/usbcopy/USBCopy_1303012145/.linktorootdir | head

      2 drwxr-xr-x   23 root     root          4096 Jul 28 19:13 .
      2 drwxr-xr-x   23 root     root          4096 Jul 28 19:13 ..
     38 drwxr-xr-x    3 root     root          4096 Apr  1 11:35 .old_patch_info

   1829 -rw-------    1 root     root          1024 Feb 26 20:21 .rnd
     32 drwxr-xr-x    3 root     root          4096 Apr  1 11:33 .syno
  15315 drwxr-xr-x    2 root     root          4096 Feb 26 20:20 .system_info
     12 drwxr-xr-x    2 root     root          4096 Apr  1 11:35 bin
     89 drwxr-xr-x   10 root     root         36864 Jul 28 19:13 dev
   1784 drwxr-xr-x   18 root     root          4096 Jul 29 09:36 etc
   3380 drwxr-xr-x   17 root     root          4096 Jul 28 19:13 etc.defaults
81143042 drwxrwxrwx    6 admin    root          4096 Jul 29 14:50 .
30671002 drwxrwxrwx    9 root     root          4096 Jul 25 23:29 ..
145895896 drwxrwxrwx    2 admin    root          4096 Feb 26 20:20 bin
145895092 drwxrwxrwx   15 admin    root          4096 Mar  2 19:17 etc.defaults
145753038 -rwxrwxrwx    1 admin    root       1589952 Dec 11  2012 linuxrc
145753040 drwxrwxrwx    2 admin    root          4096 Feb 26 20:20 sbin
145895963 drwxrwxrwx    3 admin    root          4096 Jul 29 14:50 volume1

How do I remove this folder on my NAS?

dwj

Posted 2013-07-28T03:43:08.460

Reputation: 1 384

Could you please show the output of following commands? pwd ; stat .linktorootdir / ; mount Interesting would be to compare the inode numbers – pabouk – 2013-07-29T01:31:50.507

@pabouk The interesting thing is that it is pointing to root on the NAS, not on my Mac that I have the NAS drives mounted from. So stat / shows the Mac's inode numbers. However, the directory listing I put in the post is / on the NAS. – dwj – 2013-07-29T06:37:49.650

And could you please run the commands (on the NAS)? Besides confirming that the inodes are the same it will show us the filesystem and other information. Of course from the output you can remove information which could be sensitive for you. You mentioned genesis of the files - How was the folder backed up onto the NTFS USB drive (by which tools)? How was it then transferred to the NAS? The ls -la output above is distorted as the "number of directory entries" value (second column) is always 1. – pabouk – 2013-07-29T08:27:39.640

The various distortions are most probably caused by the network filesystem you use to access the files. It is much better to do the diagnostics on the local filesystem directly on the NAS. – pabouk – 2013-07-29T08:47:42.927

@pabouk Now that I'm running on the NAS (I didn't have ssh enabled before) I can see the inodes are different. It's really looking like I have a duplicate of the entire tree in that .linktorootdir folder! As for tools for copying to the USB drive, I don't remember; this was all done over a year ago. Copying to the NAS was via direct copy from the NAS itself. – dwj – 2013-07-29T17:17:56.610

Can you do just ls -lai on both to see if it's really the same inode? It could just a copy. – ott-- – 2013-07-29T20:32:37.673

Answers

3

Solution

The files and directories in the .linktorootdir directory are copied from the root directory. You can simply delete them using for example rm -rf /volume1/usbcopy/USBCopy_1303012145/.linktohomedir.

The explanation is below.

Hardlinks of directories

Hardlinks to directories are theoretically possible but because of multiple reasons they are disabled in many systems including Linux. This also means that you will not be able to remove a hardlink to directory as the unlink() syscall will not allow it.

Demonstration

root@x:~/testdir# ln -F dir1 dir1link
ln: failed to create hard link `dir1link' => `dir1': Operation not permitted
root@x:~/testdir# unlink dir1
unlink: cannot unlink `dir1': Is a directory

The shown denial is hardwired in the Linux kernel (fs/namei.c). Here are the results of syscalls:

linkat(AT_FDCWD, "dir1", AT_FDCWD, "dir1link", 0) = -1 EPERM (Operation not permitted)
unlink("dir1")                          = -1 EISDIR (Is a directory)

Recognizing the two types of links

  • softlink - ls -l shows l as the first character of the type/permission field. stat output shows symbolic link.
  • hardlink - Hardlinks are mutually indistinguishable. Both the original file and newly created hardlink look exactly the same except the path/filename. Hardlinks cannot point from one filesystem to another. ls -i shows the same inode number for all files hardlinked to the same data (represented by inode). The second column of ls -l shows the number of hardlinks to the inode.

user1@x:~/testdir$ ls -li
total 12
6865008 drwxrwxr-x 2 user1 user1 4096 Jul 30 00:50 dir1
6822146 lrwxrwxrwx 1 user1 user1    4 Jul 30 01:44 dir1symlink -> dir1
6822155 -rw-rw-r-- 2 user1 user1   64 Jul 30 01:44 file1
6822155 -rw-rw-r-- 2 user1 user1   64 Jul 30 01:44 file1hardlink

user1@x:~/testdir$ stat * | grep -E '((File)|(Size)|(Device)):'
  File: `dir1'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 807h/2055d  Inode: 6865008     Links: 2
  File: `dir1symlink' -> `dir1'
  Size: 4           Blocks: 0          IO Block: 4096   symbolic link
Device: 807h/2055d  Inode: 6822146     Links: 1
  File: `file1'
  Size: 64          Blocks: 8          IO Block: 4096   regular file
Device: 807h/2055d  Inode: 6822155     Links: 2
  File: `file1hardlink'
  Size: 64          Blocks: 8          IO Block: 4096   regular file
Device: 807h/2055d  Inode: 6822155     Links: 2

Origin of .linktorootdir

In the .dfmdesk directory DFM creates some links during the first start. These links will be shown as icons on the desktop. Between the links there will be two links to directories: .linktorootdir as a symlink to the root directory of the system DFM is running on and also .linktohomedir. See the DFM documentation and the DFM source.

In your case the directories / and /volume1/usbcopy/USBCopy_1303012145/.linktohomedir are on different filesystems (/dev/root and /dev/vg1000/lv) so they cannot be hardlinks to the same inode. (Hardlinks can point just in the scope of a single filesystem.)

We can guess how the problem you describe emerged. Most probably the backup to NTFS was able to keep the symlink as NTFS has this capability. Later when you copied the backup from the USB drive the copying tool did not handle symlinks as expected. Instead of copying just the symbolic link itself, the tool followed the symbolic links on the source drive and copied the content of them (root directory in the case of .linktorootdir). The similar problem is describe also in the Synology forum: USBCopy cought in infinity loop while copying HDD.

The solution is described at the beginning.

pabouk

Posted 2013-07-28T03:43:08.460

Reputation: 5 358

@dwj During writing the answer I realized that I would actually need to the the basic output of stat (you added stat -f which shows information about the filesystem) to be able to describe your particular situation. Could you please add output of stat / /volume1/usbcopy/USBCopy_1303012145/.linktohomedir and ls -l / | head ; ls -l /volume1/usbcopy/USBCopy_1303012145/.linktohomedir | head ? Thank you. – pabouk – 2013-07-29T18:45:21.227

The NAS is running a version of BusyBox and has a very limited version of stat. Since ssh-ing into the box, I started poking around using your recommendations of checking out the inodes. This entire directory structure is a copy of the rest of the drive (and another that I had mounted at the time). It explains a few things: why the NAS was as full as it was and why the initial copy took so long! – dwj – 2013-07-29T21:48:48.373

One rm -fr .linkedtorootdir later and there's a ton of open space on the NAS again and I'm not sweating bullets about purging this folder. Thank you, @pabouk! – dwj – 2013-07-30T05:23:39.017

@dwj: Of course we should use -f with rm to avoid prompting. Thank you for feedback. – pabouk – 2013-07-30T07:20:58.910