Closed
Bug 225055
Opened 21 years ago
Closed 21 years ago
symlinked bookmark files are broken AGAIN
Categories
(SeaMonkey :: Bookmarks & History, defect)
SeaMonkey
Bookmarks & History
Tracking
(Not tracked)
RESOLVED
FIXED
People
(Reporter: bzbarsky, Assigned: timeless)
References
Details
(Keywords: dataloss, regression)
Attachments
(3 files, 1 obsolete file)
4.00 KB,
text/plain
|
Details | |
5.73 KB,
patch
|
benjamin
:
review+
bzbarsky
:
superreview+
|
Details | Diff | Splinter Review |
4.65 KB,
patch
|
Details | Diff | Splinter Review |
The fix for bug 200498 knowingly broke symlinked bookmark files. This is
something that has worked on Unix for a while (once it got unbroken after the
first time it had gotten broken). It can continue working if some use is made
of the nsIFile API here (the isSymlink() function and the functions to resolve
the symlink).
What we have now constitutes dataloss as far as users are concerned, since they
save bookmarks and then can't find them (when multiple profiles share a single
bookmark file, which is by far the most common reason to have it be a symlink).
![]() |
Reporter | |
Comment 1•21 years ago
|
||
By the way, I agree that the design of nsIFile makes this unnecessarily painful.
A moveToFollowingLinks or something would have helped a hell of a lot here.
![]() |
Reporter | |
Comment 2•21 years ago
|
||
OK, this is pretty nasty dataloss. Could we please get some traction here?
Especially since the other patch went in on explicit condition that this will
NOT be left just to rot?
A simple .isSymlink()/getNativeTarget() loop should do it, no?
Severity: major → critical
Flags: blocking1.7a?
Does this matter for Firebird as well? I'd like to symlink the bookmarks between
the root account on my laptop and my user account, but I saw the original bug a
long time ago and decided not to.
![]() |
Reporter | |
Comment 5•21 years ago
|
||
The firebird bug is bug 206567. This bug has nothing to do with firebird.
Comment 6•21 years ago
|
||
can someone try and get a patch together for this? it would be good to get
fixed before 1.7b
Flags: blocking1.7b?
Flags: blocking1.7a?
Flags: blocking1.7a-
Comment 7•21 years ago
|
||
> What we have now constitutes dataloss as far as users are concerned, since they
> save bookmarks and then can't find them (when multiple profiles share a single
> bookmark file, which is by far the most common reason to have it be a symlink).
use hard links as a work around?
![]() |
Reporter | |
Comment 8•21 years ago
|
||
You can't hard link a bookmarks file on your Windows partition.... (which is the
most common reason I've encountered for having multiple profiles in the first
place -- they happen to be under different OSes and our profiles save enough
OS-specific crud that actually sharing the profile is not feasible).
Comment 9•21 years ago
|
||
I have also tested hardlinks. It appears they are killed as well. mainly because
we do
* Write to a backup file.
* delete the orignal
* copy over the backup
or something similar.
On windows only NTFS supports hardlinks.
Comment 10•21 years ago
|
||
Is comment 9 right? I thought we used rename(2) or equivalent to atomicly
replace the bookmarks file. We should *never* delete the file or overwrite it
in place.
/be
Flags: blocking1.7b? → blocking1.7b+
![]() |
Reporter | |
Comment 11•21 years ago
|
||
> Is comment 9 right?
In some cases, yes.
1) On Unix if /tmp and the actual bookmarks file are on different filesystems
(rather common, since /tmp is often on its own filesystem) the rename() will
naturally fail and we will fall back on opening the bookmarks file via PR_Open
with PR_TRUNCATE and copying the data over. This shouldn't clobber hard links,
I should think. But a rename() actually _would_ clobber hard links, I believe.
Fun, eh? ;)
2) On Windows, it looks like we do the following ($dest is the filename of the
destination file, $tmp is the name of the temporary file):
A) Create $dest.moztmp
B) Call MoveFile($dest, $dest.moztmp); (this is a Windows API function that
well... moves the file).
C) Call MoveFile($temp, $dest);
D) If Step C failed, MoveFile($dest.moztmp, $dest)
I have no idea how MoveFile behaves wrt what Windows has in the way of hard links.
Comment 12•21 years ago
|
||
bz: if by clobber hard links you mean unlink the hard link (directory entry),
then yes: rename will unlink, open will truncate the hardlinked inode.
SOP for Unix says to rename from the same directory, if possible -- don't assume
/tmp is on the same fs as the file being updated. We should do that. For some
reason I thought we did, last time Ben and I looked at the bookmarks service
code (both tines of the fork).
varga: are you going to work on this for 1.7b (next week)? If not, we need
someone to step up now.
/be
![]() |
Reporter | |
Comment 13•21 years ago
|
||
OK, looks like the /tmp thing I was talking about is a non-issue now -- we put
the temp file in the same dir as the bookmarks file. So hard links won't work,
since rename() will simply unlink the hard link instead of overwriting the file
it points to, just like it'll unlink the soft link (what this bug is about).
The right thing to do would seem to be to follow the soft link, if any, before
we create the temp file, so that we preserve the "temp file and actual bookmarks
file are in the same directory" invariant.
Comment 14•21 years ago
|
||
Reminder to fix this in the Firefox tine of the fork, too. File a separate bug
you say? Cc'ing Ben.
/be
Assignee | ||
Comment 15•21 years ago
|
||
Assignee: varga → timeless
Status: NEW → ASSIGNED
Attachment #143269 -
Flags: superreview?(bzbarsky)
Attachment #143269 -
Flags: review?(bsmedberg)
Assignee | ||
Comment 16•21 years ago
|
||
Comment 17•21 years ago
|
||
Comment on attachment 143269 [details] [diff] [review]
fix symlinked bookmark files again
> rv = tempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, /*octal*/ 0600);
> NS_ENSURE_SUCCESS(rv, rv);
1) If the tempfile doesn't exist, createUnique won't return a random filename,
it will return the actual file. Then your ->Equals check below will fail. Can't
we just change the ->Equals to return NS_OK if the tempfile is the same as
bookmarksfile.
>+ // If we wrote to the file successfully (i.e. if the disk wasn't full)
>+ // then move the temp file to the bookmarks file so it takes its place.
>+ PRBool equals;
>+ rv = tempFile->Equals(aBookmarksFile, &equals);
>+ if (NS_FAILED(rv))
>+ break;
>+ NS_ENSURE_TRUE(!equals, NS_ERROR_FAILURE);
>+ PRUint32 oldPermissions = 0600;
>+ rv = aBookmarksFile->GetPermissions(&oldPermissions);
>+ if (NS_FAILED(rv))
>+ oldPermissions = 0600;
>+ aBookmarksFile->SetPermissions(oldPermissions);
2) move the permissions-copying up to the CreateUnique call, unless there is an
issue I'm missing with that.
Attachment #143269 -
Flags: review?(bsmedberg) → review-
Attachment #143269 -
Flags: superreview?(bzbarsky)
Assignee | ||
Comment 18•21 years ago
|
||
Attachment #143269 -
Attachment is obsolete: true
Attachment #143285 -
Flags: review?(bsmedberg)
Updated•21 years ago
|
Attachment #143285 -
Flags: superreview?(bzbarsky)
Attachment #143285 -
Flags: review?(bsmedberg)
Attachment #143285 -
Flags: review+
![]() |
Reporter | |
Comment 19•21 years ago
|
||
Can you attach diff -w so I can tell what exactly got changed in that big block
you reindented?
Assignee | ||
Comment 20•21 years ago
|
||
it's nowhere near as useful as you'd think, because i also renamed variables to
a local version which i modified. I could have just assigned the local comptr
to the argument variable, but that'd eventually confuse someone...
![]() |
Reporter | |
Comment 21•21 years ago
|
||
Comment on attachment 143291 [details] [diff] [review]
143285 -w
It's actually reviewable unlike the other....
>Index: nsBookmarksService.cpp
>+ rv = bookmarksFile->Normalize();
Add a comment as to why this Normalize() call is needed (because Unix ignores
the followSymlinks thing, yadda, yadda).
> rv = NS_NewLocalFileOutputStream(getter_AddRefs(out),
> tempFile,
> PR_WRONLY,
> /*octal*/ 0600,
> 0);
>- if (NS_FAILED(rv))
Um... You do want to check rv here. And break on failure.
> strm->Close();
> out->Close();
The rv of those should be checked too (I know the old code didn't do it,
but...) since some data can actually attempt to be writte on close (eg over
NSF), according to brendan.
With that, sr=bzbarsky
![]() |
Reporter | |
Updated•21 years ago
|
Attachment #143285 -
Flags: superreview?(bzbarsky) → superreview+
Assignee | ||
Comment 22•21 years ago
|
||
mozilla/xpfe/components/bookmarks/src/nsBookmarksService.cpp 1.309
mozilla/xpfe/components/bookmarks/src/nsBookmarksService.cpp 1.311
firebird already has a bug, it's in the dependency list.
Status: ASSIGNED → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Since I don't use symlinked bookmark files (the Bookmarks FTP extension takes
care of such needs), removing self from CC list.
Updated•20 years ago
|
Product: Browser → Seamonkey
You need to log in
before you can comment on or make changes to this bug.
Description
•