coreutils
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]