Closed
Bug 974225
Opened 11 years ago
Closed 11 years ago
[mozfile] remove() fails with '[Errno 1] Operation not permitted' when trying to update permissions for a symlink to a system folder
Categories
(Testing :: Mozbase, defect)
Testing
Mozbase
Tracking
(Not tracked)
RESOLVED
FIXED
mozilla30
People
(Reporter: mcomella, Assigned: whimboo)
References
Details
Attachments
(2 files, 2 obsolete files)
|
1.10 KB,
text/plain
|
Details | |
|
4.79 KB,
patch
|
ahal
:
review+
|
Details | Diff | Splinter Review |
This causes an attempted removal of /usr/include/python2.7, but mach exits before completing this.
Comment 1•11 years ago
|
||
Caused by 949600 which has been backed out.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → DUPLICATE
| Assignee | ||
Comment 2•11 years ago
|
||
Actually lets morph this bug because that's a problem with mozfile and not mach. It will block the next merge try.
Blocks: 949600
Status: RESOLVED → REOPENED
Component: mach → Mozbase
OS: Linux → All
Product: Core → Testing
QA Contact: hskupin
Hardware: x86_64 → All
Resolution: DUPLICATE → ---
Summary: `mach clobber` attempts to remove what symlinks point to → [mozfile] remove() attempts to modify/remove what symlinks point to
| Assignee | ||
Updated•11 years ago
|
Assignee: nobody → hskupin
Status: REOPENED → ASSIGNED
| Assignee | ||
Comment 3•11 years ago
|
||
Actually this is pretty easy to reproduce on Linux:
$ ln -s /usr/share/ to_delete
$ python -c 'import mozfile; mozfile.remove("_delete")'
I will have a patch soon and will also try to find a test for that, so we do not regress again.
Summary: [mozfile] remove() attempts to modify/remove what symlinks point to → [mozfile] remove() fails with '[Errno 1] Operation not permitted' when trying to remove a symlink to a system folder
| Assignee | ||
Comment 4•11 years ago
|
||
Well, actually the permission change call fails because chmod itself fails when calling it directly:
$ chmod 0700 _delete
chmod: changing permissions of ‘_delete’: Operation not permitted
So it looks like you cannot change the permission of a symlink, and we should simply return early in _update_permissions.
Summary: [mozfile] remove() fails with '[Errno 1] Operation not permitted' when trying to remove a symlink to a system folder → [mozfile] remove() fails with '[Errno 1] Operation not permitted' when trying to update permissions for a symlink to a system folder
| Assignee | ||
Comment 5•11 years ago
|
||
Silly mistakes! So what does this patch change:
* We do no longer call os.chmod() on symlinks as mentioned above. There is nothing it would change because they already have all the needed permissions
* We call os.stat() for each file and dir we check, and not only once for the path passed into remove(). So all the files/dirs should get the right permissions assigned to.
Attachment #8378293 -
Flags: review?(ahalberstadt)
Comment 6•11 years ago
|
||
Comment on attachment 8378293 [details] [diff] [review]
Patch v1
Review of attachment 8378293 [details] [diff] [review]:
-----------------------------------------------------------------
Looks good! One optional readability improvement suggested.
::: mozfile/mozfile/mozfile.py
@@ +184,1 @@
> mode = dir_mode if os.path.isdir(path) else file_mode
This would probably be better as:
if os.path.isdir(path):
mode = ...
else:
mode = ...
Attachment #8378293 -
Flags: review?(ahalberstadt) → review+
Comment 7•11 years ago
|
||
Comment on attachment 8378293 [details] [diff] [review]
Patch v1
Review of attachment 8378293 [details] [diff] [review]:
-----------------------------------------------------------------
::: mozfile/mozfile/mozfile.py
@@ +184,1 @@
> mode = dir_mode if os.path.isdir(path) else file_mode
There's a lot of system calls here! We need to keep the system calls in check because they can degrade performance on Windows.
e.g. the |os.path.isdir(path)| is equivalent to |stat.S_ISDIR(path_stats.st_mode)| but the latter doesn't perform a system call.
I'd file a follow-up to optimize this code for common case (no permissions adjustment needed - just attempt delete, catch exception and adjust permissions and retry) and minimizes the number of system calls.
| Assignee | ||
Comment 8•11 years ago
|
||
(In reply to Andrew Halberstadt [:ahal] from comment #6)
> This would probably be better as:
>
> if os.path.isdir(path):
> mode = ...
> else:
> mode = ...
Yes, that was what I mentioned on IRC. I will do that.
(In reply to Gregory Szorc [:gps] from comment #7)
> There's a lot of system calls here! We need to keep the system calls in
> check because they can degrade performance on Windows.
>
> e.g. the |os.path.isdir(path)| is equivalent to
> |stat.S_ISDIR(path_stats.st_mode)| but the latter doesn't perform a system
> call.
>
> I'd file a follow-up to optimize this code for common case (no permissions
> adjustment needed - just attempt delete, catch exception and adjust
> permissions and retry) and minimizes the number of system calls.
Very good point. I will get this addressed. There shouldn't be a need for a follow-up bug. It's an easy change.
| Assignee | ||
Comment 9•11 years ago
|
||
(In reply to Henrik Skupin (:whimboo) from comment #8)
> > I'd file a follow-up to optimize this code for common case (no permissions
> > adjustment needed - just attempt delete, catch exception and adjust
> > permissions and retry) and minimizes the number of system calls.
>
> Very good point. I will get this addressed. There shouldn't be a need for a
> follow-up bug. It's an easy change.
Looks like I have some trouble with stat.S_ISLNK() and that it doesn't really detect a symlink. So I would say, lets get this really addressed in a follow-up bug.
| Assignee | ||
Comment 10•11 years ago
|
||
Updated patch, and with 3 new tests included now.
Attachment #8378293 -
Attachment is obsolete: true
Attachment #8378433 -
Flags: review?(gps)
Attachment #8378433 -
Flags: review?(ahalberstadt)
| Assignee | ||
Comment 11•11 years ago
|
||
It looks like that os.geteuid() is not available on Windows. So I have to find another way to skip the sympath test for root users.
| Assignee | ||
Comment 12•11 years ago
|
||
Fixed the skipIf() issue with a single call. All runs fine across platforms.
Attachment #8378433 -
Attachment is obsolete: true
Attachment #8378433 -
Flags: review?(gps)
Attachment #8378433 -
Flags: review?(ahalberstadt)
Attachment #8378447 -
Flags: review?(gps)
Attachment #8378447 -
Flags: review?(ahalberstadt)
Comment 13•11 years ago
|
||
Comment on attachment 8378447 [details] [diff] [review]
Patch v2.1
Review of attachment 8378447 [details] [diff] [review]:
-----------------------------------------------------------------
Looks good.
::: mozfile/tests/test_remove.py
@@ +137,5 @@
> mozfile.remove(filepath)
>
> self.assertFalse(os.path.exists(filepath))
> +
> + @unittest.skipIf(mozinfo.isWin, "Symlinks are not supported on Windows")
Instead of mozinfo.isWin you could do "not hasattr(os, 'symlink')"
Attachment #8378447 -
Flags: review?(ahalberstadt) → review+
| Assignee | ||
Comment 14•11 years ago
|
||
Comment on attachment 8378447 [details] [diff] [review]
Patch v2.1
Talked with Andrew on IRC and it should be enough to have a single reviewer here.
Attachment #8378447 -
Flags: review?(gps)
| Assignee | ||
Comment 15•11 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 11 years ago → 11 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
| Assignee | ||
Updated•11 years ago
|
Target Milestone: --- → mozilla30
You need to log in
before you can comment on or make changes to this bug.
Description
•