0

On an ext4 filesystem, I have a base dir which itself has three dirs a, b and c, and each dir has various contents inside.

I set chattr +a base and then executed rm -r base. Then I found a, b, c were still there. Nice. Then I found they all became empty. I cried.

What happened?

Cyker
  • 205
  • 2
  • 10

3 Answers3

4

I don't see why you are surprised at this. A directory is just a file. A directory entry is a pointer to a file. When you set chattr +a on base you only affect base, so you can't remove entries from it. The directories a,b and c are files too but they are not affected by the attributes of base other than you can't remove them from base.

user9517
  • 114,104
  • 20
  • 206
  • 289
  • Remember that `rm -r` asks you whether to descend a into write-protected directory? Nice. I expected that it would notice `base` is deletion-protected in its preorder traversal and give a notice. Then I looked at its source code and found it's not the case. I cried. – Cyker Nov 22 '15 at 18:22
  • Yes, but only base is write protected not the directories underneath it. – user9517 Nov 22 '15 at 18:33
  • Wt problem are you actually trying to solve, why are you crying ? – user9517 Nov 22 '15 at 18:41
  • You can answer *no* when `rm` gives you the notice so that you stay safe. It doesn't give me a notice in this case. In short, I want to prevent a mis-deletion. Details are put as a comment to another answer. – Cyker Nov 22 '15 at 18:48
  • Oh right, there is no good solution to that. You can `alias rm='rm -i'` which may work for you. – user9517 Nov 22 '15 at 18:55
  • This may be useful too http://serverfault.com/questions/337082/how-do-i-prevent-accidental-rm-rf – user9517 Nov 22 '15 at 18:59
  • That thread is interesting. I guess I have to use a wrapper but the world is probably better if we don't need two processes for every safe rm. – Cyker Nov 22 '15 at 20:10
1

chattr is used to change file attributes on linux file system.

So, when you use chattr +a it only affects the base directory itself and the subdirectories and files directly under it.

Why?

The term directory is used in a computer software context to refer to what appears to the user to be a container or folder that can hold files and other directories.

In Linux and other Unix-like operating system, everything on the system is treated as being a file, and a directory is thus considered to be just a special type of file that contains a list of file names and the corresponding inodes for each file and directory that it appears to contain. An inode is a data structure on a filesystem that stores all the information about a file except its name and its actual data.

Therefore, it can be useful to think of the word directory as being an abbreviation for the term directory file. Although perhaps technically redundant, it is convenient and common to use expressions such as files and directories when referring to the contents of a directory; an alternative is filesystem objects.

Ref: http://www.linfo.org/directory.html

When you use rm -r base, it runs recursively (-r option) and tries to remove all the files and subdirectories and their contents but it fails to remove the base directory and the directories and files directly under it. But it successfully removes the files under the subdirectories.

As for the a (append) attribute, you can add directories and files under it without any problem, but you can not delete or rename them. For me, it behaves perfectly as a file with it subdirectories and files directly under it.

What you wanted to achieve, to protect the directory and all the subdirctories and files under it, you should have used the -R option to set or add the attribute Recursively to each and all. As documentd here:http://linux.die.net/man/1/chattr

Diamond
  • 8,791
  • 3
  • 22
  • 37
  • Thank you and I think most of the stuff here are good and in-point. But actually I want to be able to freely add/modify/delete files in `base`. What I want to avoid is a recursive deletion of `base` by mistake. Setting `base` as write-protected lets `rm -r base` give a notice. That's good but also means I cannot add/modify/delete files in `base`. Setting `base` with `chattr +i` has a similar effect. Setting `base` with `chattr +a` gives more freedom but `rm` regretfully doesn't care about this option until the last step. – Cyker Nov 22 '15 at 18:34
  • I think, your question was about __why did it happend, what happened__, and I have tried to explain it my best. For what you want to achieve, I don't see any option in `chattr`. You have to find out the best combination that closely fits your need, just think in the context of `file` and not `directory`. You can also ask a new question for that. – Diamond Nov 22 '15 at 18:54
  • I thought I could get some light shed upon by more details of `rm` and `chattr`. From your answer it turns out that `chattr` doesn't seem to be the correct path towards the solution. Actually the solution only requires a tiny check in `rm` preorder traversal. But it's a *core* util and I'm wondering about any implications given by its change. – Cyker Nov 22 '15 at 19:06
0

The "a" attribute can only be applied to files (once applied, they only can be open in append mode for writing). The behaviour of applying this attribute to directories is not defined.

dr_
  • 1,035
  • 11
  • 19