[comp.unix.questions] removing hard linked directories

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (03/20/91)

How would you recommend removing a directory that is linked under several
different names?  The directory really is empty but rmdir lies and says
it is not empty.
-- 

 /***************************************************************************\
< Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu                              >
 \***************************************************************************/

jik@athena.mit.edu (Jonathan I. Kamens) (03/20/91)

In article <1991Mar20.013744.12749@ux1.cso.uiuc.edu>, phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
|> How would you recommend removing a directory that is linked under several
|> different names?  The directory really is empty but rmdir lies and says
|> it is not empty.

  Well, first of all, perhaps you already know this, but the problem you are
having is just one of the many reasons why the man pages for ln(1) and link(2)
say that you shouldn't create hard links to directories.  There are other
reasons, like creating circles in the filesystem that can confuse various
oft-used system utilities.

  Second, my version of "fsck" automatically deals with hard links to
directories.  I created the directory /foo on a filesystem and then
hard-linked /bar to it, and when I ran fsck, got "/bar IS AN EXTRANEOUS HARD
LINK TO DIRECTORY /foo\n\nREMOVE? "

  If your fsck isn't smart enough to do that, then you can help it along a
little bit by figuring out the inode number of the directory with multiple
links, unmounting the filesystem and then running "clri" on the inode.  When
you do this, fsck should be able to clean up.  This worked for me too.  Fsck
asked a few questions about the directories in question, I said yes to all of
them and the directories went away.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

gwyn@smoke.brl.mil (Doug Gwyn) (03/21/91)

In article <1991Mar20.013744.12749@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>How would you recommend removing a directory that is linked under several
>different names?  The directory really is empty but rmdir lies and says
>it is not empty.

You remove the extra links essentially the same way that you created them:
have effective UID 0 perform unlink() operations.  Some systems may have
"link" and "unlink" utilities for use by the superuser.

rmilner@zia.aoc.nrao.edu (Ruth Milner) (03/21/91)

In article <1991Mar20.115508.25638@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes:
>In article <1991Mar20.013744.12749@ux1.cso.uiuc.edu>, phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>|> How would you recommend removing a directory that is linked under several
>|> different names?  The directory really is empty but rmdir lies and says
>|> it is not empty.
>
>  Well, first of all, perhaps you already know this, but the problem you are
>having is just one of the many reasons why the man pages for ln(1) and link(2)
>say that you shouldn't create hard links to directories.  

(I'm not the poster of the original question, but this just happened to me).

So would somebody please tell me why "mv" will do this?

Scenario: directory in /tmp belonging to someone else. I forget it isn't
mine, come along (just me, not root) and mv it. Result: mv says "not
owner", but by that time it has already created the new directory *and did
not clean it up*. Not nice.

When I did an rm -r on one of them (as root), the contents of both 
disappeared (makes sense), but rm/rmdir would not get rid of the directories.

>  Second, my version of "fsck" automatically deals with hard links to
>directories.  I created the directory /foo on a filesystem and then
>hard-linked /bar to it, and when I ran fsck, got "/bar IS AN EXTRANEOUS HARD
>LINK TO DIRECTORY /foo\n\nREMOVE? "

Guess I'll have to do this single-user manually. The normal multi-user
boot fsck said

  /tmp/baddir2 IS AN EXTRANEOUS LINK TO DIRECTORY /tmp/baddir, IGNORED

>links, unmounting the filesystem and then running "clri" on the inode.  When
>you do this, fsck should be able to clean up.  

Thank you, thank you!
-- 
Ruth Milner
Systems Manager                     NRAO/VLA                    Socorro NM
                            rmilner@zia.aoc.nrao.edu

kimcm@diku.dk (Kim Christian Madsen) (03/21/91)

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:

>How would you recommend removing a directory that is linked under several
>different names?  The directory really is empty but rmdir lies and says
>it is not empty.

Supposing that you're running SysV (or something like it) you probably
have an utility in called unlink in /etc. This will do the job,
unfortunately you will have to be root to execute this, since it does
not perform the usual tests that rm/rmdir would do.

					Regards,
					Kim Chr. Madsen

jik@athena.mit.edu (Jonathan I. Kamens) (03/21/91)

In article <1991Mar21.025311.9821@nmt.edu>, rmilner@zia.aoc.nrao.edu (Ruth Milner) writes:
|> Scenario: directory in /tmp belonging to someone else. I forget it isn't
|> mine, come along (just me, not root) and mv it. Result: mv says "not
|> owner", but by that time it has already created the new directory *and did
|> not clean it up*. Not nice.

  Sounds like you've got an odd version of mv.  Here's what happens on my
(4.3BSD-like) system:

	% pwd
	/site/tmp
	% ls -ldg foo
	drwxrwxr-x  2 daemon   wheel         512 Mar 21 04:55 foo/
	% whoami
	jik
	% mv foo bar
	mv: foo: rename: Not owner
	% ls -ldg foo bar
	bar not found (No such file or directory)
	drwxrwxr-x  2 daemon   wheel         512 Mar 21 04:55 foo/

In other words, if the mv fails, the mv fails.  Indeed, I believe that the mv
command is documented as guaranteeing that if the rename fails, the original
file is left unchanged and undamaged.

  Staring at the source code for mv on my system, it appears that directories
are moved using an atomic rename system call.  If your mv is behaving as
you've described, then either (a) the rename system call in your kernel is
brain-damaged, or (b) you've got a brain-damaged version of mv.

  What kind of machine and OS are you working on?

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

asg@sage.cc.purdue.edu (Bruce Varney) (03/21/91)

In article <1991Mar21.100031.12027@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes:
}In article <1991Mar21.025311.9821@nmt.edu>, rmilner@zia.aoc.nrao.edu (Ruth Milner) writes:
}|> Scenario: directory in /tmp belonging to someone else. I forget it isn't
}|> mine, come along (just me, not root) and mv it. Result: mv says "not
}|> owner", but by that time it has already created the new directory *and did
}|> not clean it up*. Not nice.
}
}  Sounds like you've got an odd version of mv.  Here's what happens on my
}(4.3BSD-like) system:
}
}  Staring at the source code for mv on my system, it appears that directories
}are moved using an atomic rename system call.  If your mv is behaving as
}you've described, then either (a) the rename system call in your kernel is
}brain-damaged, or (b) you've got a brain-damaged version of mv.

Some versions of UNIX do not have the rename() call. As such, to do a mv,
they implement a link(), then an unlink(). Here is what probably happened. 
The / directory was 1777. The mv command was successful up to the link(),
but then the unlink() failed because you did not own the directory, and the
sticky bit was left on. You were thus left with a hard link to the directory.

Johnathan, you must really quit being so condescending to people. 90% of
your responses include "this belongs in another newsgroup not this one"'s.
(although this particular article does not) Just because you think a 
certain topic is not appropriate does not mean others don't think it is.
And in fact, I just got done reading a 30+ line response from you that
had 29+ lines of "you could ftp to here for the FAQ, or mail to here, or
post to here, or do this" and only one line of help - talk about wasting
bandwidth!!!!!!

(Not that I am never guilty :-) )
}
}  What kind of machine and OS are you working on?
Probably SYSV. If I remember right SYSV does not have the rename() call.
}
}-- 
}Jonathan Kamens			              USnail:
						      ^^^^^^????
Get out your UShammers.

}MIT Project Athena				11 Ashford Terrace
}jik@Athena.MIT.EDU				Allston, MA  02134
}Office: 617-253-8085			      Home: 617-782-0710


		The Grand Master
---------
sar.casm \'sa:r-.kaz-*m\ \sa:r-'kas-tik\ \-ti-k(*-)le-\ n [F sarcasme, fr. 
   LL sarcasmos, fr. Gk sarkasmos, fr. sarkazein to tear flesh, bite the lips 
   in rage, sneer, fr. sark-, sarx flesh; akin to Av thwar*s to cut] 1: a 
   cutting, hostile, or contemptuous remark : GIBE 2: the use of caustic or 
   ironic language - sar.cas.tic aj

                                   ###             ##
Courtesy of Bruce Varney           ###               #
aka -> The Grand Master                               #
asg@sage.cc.purdue.edu             ###    #####       #
PUCC                               ###                #
;-)                                 #                #
;'>                                #               ##

jik@athena.mit.edu (Jonathan I. Kamens) (03/22/91)

In article <8413@mentor.cc.purdue.edu>, asg@sage.cc.purdue.edu (Bruce Varney) writes:
|> In article <1991Mar21.100031.12027@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes:
|> }  Staring at the source code for mv on my system, it appears that directories
|> }are moved using an atomic rename system call.  If your mv is behaving as
|> }you've described, then either (a) the rename system call in your kernel is
|> }brain-damaged, or (b) you've got a brain-damaged version of mv.
|> 
|> Some versions of UNIX do not have the rename() call. As such, to do a mv,
|> they implement a link(), then an unlink(). Here is what probably happened. 
|> The / directory was 1777. The mv command was successful up to the link(),
|> but then the unlink() failed because you did not own the directory, and the
|> sticky bit was left on. You were thus left with a hard link to the directory.

  A kernel without an atomic rename operation (or, at least, a rename
operation that tries to be atomic, although it might fail to be completely
atomic in the case of some network filesystems) is, in my opinion,
brain-damaged.  Which is what I said in my original message.  Thank you for
spelling out the particular form the brain-damage takes in this case :-).

|> Johnathan,

  It's Jonathan.

|> 90% of
|> your responses include "this belongs in another newsgroup not this one"'s.

  There are certain cases in which it is clear that articles do not belong. 
Questions about deleting a file whose name starts with '-' or about undeleting
a file, for example, do not belong in comp.unix.wizards.  Questions about
PostScript do not belong in comp.unix.questions (unless they are about using
PostScript under Unix).

|> (although this particular article does not) Just because you think a 
|> certain topic is not appropriate does not mean others don't think it is.

  If you are thinking of a particular case in which I incorrectly said that a
message was inappropriate for a newsgroup, I would like to hear about it, and
I will try not to do that in the future.

  But I do not consider it wrong to tell someone when the post a message in
the wrong newsgroup, nor do I consider it "condescending," and I will continue
to do so.  I will also usually answer the question they asked in addition to
telling them where it should have been posted.  I am going to continue to do
this, so flaming me about it is going to do you little good, and if you want
to do so, I suggest you do it in E-mail and not on the net.

  Incidentally, I have received E-mail from several people who believe that
what I do is a good thing.  To paraphrase you, "Just because you think what
I'm doing is not appropriate does not mean that other people don't think it
is."

|> And in fact, I just got done reading a 30+ line response from you that
|> had 29+ lines of "you could ftp to here for the FAQ, or mail to here, or
|> post to here, or do this" and only one line of help - talk about wasting
|> bandwidth!!!!!!

  The "29+" lines were instructions for getting the FAQ for a newsgroup in
which the FAQ has expired at many sites.  Furthermore, they explained how to
use a new archive server which archives the FAQ's for *every newsgroup*.  That
is certainly not "wasting bandwidth," it is useful information.

  If you want to talk about the issue of rename and the kernel, then I will
continue to do that.  But I will not post any more articles in this thread
about how or what I choose to post.  There is no point to it.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

rmk@rmkhome.UUCP (Rick Kelly) (03/22/91)

In article <1991Mar20.013744.12749@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>How would you recommend removing a directory that is linked under several
>different names?  The directory really is empty but rmdir lies and says
>it is not empty.


Try using rm -r.


Rick Kelly	rmk@rmkhome.UUCP	frog!rmkhome!rmk	rmk@frog.UUCP

jik@athena.mit.edu (Jonathan I. Kamens) (03/23/91)

In article <9103211912.08@rmkhome.UUCP>, rmk@rmkhome.UUCP (Rick Kelly) writes:
|> In article <1991Mar20.013744.12749@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
|> >How would you recommend removing a directory that is linked under several
|> >different names?  The directory really is empty but rmdir lies and says
|> >it is not empty.
|> 
|> Try using rm -r.

  This will not work.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

(It is generally considered a good idea to actually *test* your answers when
you are not sure about them, before you post them to the net and thereby force
them to be transmitted all over the world.)

les@chinet.chi.il.us (Leslie Mikesell) (03/23/91)

In article <1991Mar21.200251.2272@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes:

>  A kernel without an atomic rename operation (or, at least, a rename
>operation that tries to be atomic, although it might fail to be completely
>atomic in the case of some network filesystems) is, in my opinion,
>brain-damaged.  Which is what I said in my original message.  Thank you for
>spelling out the particular form the brain-damage takes in this case :-).

Welcome to the wonderful world of SysV, where you can't safely do
something as simple as maintain your configuration files in multi-user
mode.  The fact that there is a point where both links appear is
the least of the problems.  Since link() will fail if the destination
already exists, you must unlink the existing copy first, leaving an
indeterminate amount of time where the filename does not exist at all
until you get around to linking the new copy under the old name.

Les Mikesell
  les@chinet.chi.il.us

cudcv@warwick.ac.uk (Rob McMahon) (03/26/91)

In article <1991Mar21.025311.9821@nmt.edu> rmilner@zia.aoc.nrao.edu (Ruth
Milner) writes: 
>In article <1991Mar20.115508.25638@athena.mit.edu> jik@athena.mit.edu
(Jonathan I. Kamens) writes:
>>the problem you are having is just one of the many reasons why the man pages
>>for ln(1) and link(2) say that you shouldn't create hard links to
>>directories.
>
>So would somebody please tell me why "mv" will do this?

For a long time SunOS had a bug where if you had a sticky /tmp directory, and
you tried to move someone else's directory, rename() would create a new link
to the directory, try to unlink the old one, fail, try to unlink the new one,
and fail.  Then I'd come along as super-user and try to /etc/unlink the new
version, and it would fail.  The only way out was to halt the machine and do a
manual fsck (the automatic fsck would just let it pass as you say).

I complained to Sun that a) rename() shouldn't leave these extraneous links
around and b) unlink should allow them to be removed even if they did, but the
people I talked to at Sun seemed to think this was a feature, which would not
be fixed.  Meanwhile we've gone to SunOS 4.1{,.1}, and I don't know if the
problem still exists, it's too much of a pain to try it out.

No doubt next term we'll get a new batch of these fun links called "Freddy
you're a bozo" which seem to amuse some of the undergraduates, and I'll be
complaining to Sun again.

Cheers,

Rob
-- 
UUCP:   ...!mcsun!ukc!warwick!cudcv	PHONE:  +44 203 523037
JANET:  cudcv@uk.ac.warwick             INET:   cudcv@warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England

guy@auspex.auspex.com (Guy Harris) (03/27/91)

>Some versions of UNIX do not have the rename() call. As such, to do a mv,
>they implement a link(), then an unlink(). Here is what probably happened.

Well, maybe.

On the other hand, I've seen Ms. Milner post in "comp.sys.sun" in the
past; if the machine in question is a Sun, its version of UNIX most
definitely has "rename()" (her postings indicated that she's not running
Sun-1s with Unisoft V7 :-)).  And yes, the Sun code *is*, in fact, a bit
brain-damaged; the "rename()" code gets halfway through the operation,
and then bails out because the directory is sticky, without backing the
stuff it's already done out.

rmilner@zia.aoc.nrao.edu (Ruth Milner) (03/27/91)

In article <6833@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>>Some versions of UNIX do not have the rename() call. As such, to do a mv,
>>they implement a link(), then an unlink(). Here is what probably happened.
>
>Well, maybe.
>
>On the other hand, I've seen Ms. Milner post in "comp.sys.sun" in the
>past; if the machine in question is a Sun, its version of UNIX most
>definitely has "rename()" (her postings indicated that she's not running
>Sun-1s with Unisoft V7 :-)).  

In this particular instance, it's a Solbourne running OS/MP 4.0c = SunOS 4.0.3.
I'd try it on some of my "real" Suns, but I'm not keen on the results :-}.

>And yes, the Sun code *is*, in fact, a bit
>brain-damaged; the "rename()" code gets halfway through the operation,
>and then bails out because the directory is sticky, without backing the
>stuff it's already done out.

Only the parent directory, /usr/tmp itself, was sticky, not the directory I 
was attempting to mv - or is this what you mean?
-- 
Ruth Milner
Systems Manager                     NRAO/VLA                    Socorro NM
                            rmilner@zia.aoc.nrao.edu

bernie@metapro.DIALix.oz.au (Bernd Felsche) (03/29/91)

In article <1991Mar20.013744.12749@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>How would you recommend removing a directory that is linked under several
>different names?  The directory really is empty but rmdir lies and says
>it is not empty.

fsdb and reduce the link count to 2. then run fsck.

with sysv, you shouldn't have the multiple hard links anyway, except
to sub-directories, unless... perhaps:

there is a process still running, with its working directory in limbo,
below the directory you are trying to remove.

-- 
Bernd Felsche,                 _--_|\   #include <std/disclaimer.h>
Metapro Systems,              / sale \  Fax:   +61 9 472 3337
328 Albany Highway,           \_.--._/  Phone: +61 9 362 9355
Victoria Park,  Western Australia   v   Email: bernie@metapro.DIALix.oz.au