[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How is mv done across filesystem?
From: |
Bernhard Voelker |
Subject: |
Re: How is mv done across filesystem? |
Date: |
Sun, 12 Jan 2014 18:25:45 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 |
On 01/12/2014 06:09 PM, Peng Yu wrote:
> Hi,
>
> It seems the following command across filesystem
>
> mv /filesystem1/src /filesystem2/dst
>
> is roughly equivalent to the following. The idea is that no files will
> be deleted from the src unless all files are correctly copied to dst.
> Is it so?
>
> cp -p -r /filesystem1/src /filesystem2/dst
> rm -rf /filesystem2/dst
I bet you meant
rm -rf /filesystem1/src
for the latter command. ;-)
> Does anybody know the exact equivalent commands to mv so that I can
> understand what mv does? Thanks.
The processing depends a bit on the type of 'src' and 'dst', and
whether 'dst' exists or not.
Given the easiest case - where 'src' is a regular file and 'dst'
does not exist, an 'strace' will show you what mv(1) does:
Query information about src and dest:
stat("/filesystem2/dst", 0x7fff161f08e0) = -1 ENOENT (No such file or
directory)
lstat("/filesystem1/src", {st_mode=S_IFREG|0644, st_size=68, ...}) = 0
lstat("/filesystem2/dst", 0x7fff161f05a0) = -1 ENOENT (No such file or
directory)
Try a simple rename (which fails):
rename("/filesystem1/src", "/filesystem2/dst") = -1 EXDEV (Invalid
cross-device link)
Try to remove dst (probably obsolete in this case):
unlink("/filesystem2/dst") = -1 ENOENT (No such file or
directory)
Open src for reading and dst for writing:
open("/filesystem1/src", O_RDONLY|O_NOFOLLOW) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=68, ...}) = 0
open("/filesystem2/dst", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
Copy data:
read(3, " 18:14pm up 1 day 5:23, 8 use"..., 65536) = 68
write(4, " 18:14pm up 1 day 5:23, 8 use"..., 68) = 68
read(3, "", 65536) = 0
Setting timestamp on dst:
utimensat(4, NULL, {{1389546891, 750964678}, {1389546891, 754965246}}, 0) = 0
Trying to copy extended attributes.
flistxattr(3, NULL, 0) = 0
flistxattr(3, "", 0) = 0
fgetxattr(3, "system.posix_acl_access", 0x7fff161f0220, 132) = -1 ENODATA (No
data available)
fstat(3, {st_mode=S_IFREG|0644, st_size=68, ...}) = 0
fsetxattr(4, "system.posix_acl_access",
"\x02\x00\x00\x00\x01\x00\x06\x00\xff\xff\xff\xff\x04\x00\x04\x00\xff\xff\xff\xff
\x00\x04\x00\xff\xff\xff\xff", 28, 0) = 0
Close both files:
close(4) = 0
close(3) = 0
Stat the file system root directory of dst:
lstat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
and the src again:
newfstatat(AT_FDCWD, "/filesystem1/src", {st_mode=S_IFREG|0644, st_size=68,
...}, AT_SYMLINK_NOFOLLOW) = 0
Remove src.
unlinkat(AT_FDCWD, "/filesystem1/src", 0) = 0
Some of the above steps don't seem to be necessary for the simple
case but will be needed for more complex cases like moving directory structures,
different permission modes, extended attributes, error handling etc.
Finally, as coreutils is open source, you're of course free to read
the sources yourself:
http://git.sv.gnu.org/cgit/coreutils.git/tree/src/mv.c
and
http://git.sv.gnu.org/cgit/coreutils.git/tree/src/copy.c
The latter contains code which is common among mv and cp.
Have a nice day,
Berny