LoginSignup
7
7

More than 5 years have passed since last update.

Goのos.RenameはLinuxではちゃんとrename(2)を使っているのか

Last updated at Posted at 2015-02-12

それはまあ、そうだろうとは思うのだが、本当にそうか(すなわちアトミックにファイル操作するのか)を確認した。

renamer.go
package main

import "os"

func main() {
    dest := os.Args[1]
    src := os.Args[2]

    if e := os.Rename(dest, src); e != nil {
        panic(e)
    }
}

こういうなんてことの無いプログラムをビルドし、手頃なLinux amd64のVMで strace を走らせる。

[vagrant@www tmp]$ strace ./renamer sample sample.1
execve("./renamer", ["./renamer", "sample", "sample.1"], [/* 22 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x4bcb30)       = 0
sched_getaffinity(0, 128, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) = 128
mmap(0xc000000000, 65536, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000
munmap(0xc000000000, 65536)             = 0
mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff4f672d000
mmap(0xc208000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc208000000
mmap(0xc207ff0000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc207ff0000
mmap(0xc000000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff4f671d000
mmap(NULL, 1439992, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff4f65bd000
sigaltstack({ss_sp=0xc208002000, ss_flags=0, ss_size=32768}, NULL) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGHUP, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGHUP, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGQUIT, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGILL, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGTRAP, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGABRT, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGBUS, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGFPE, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGUSR1, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGSEGV, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
...
rt_sigaction(SIGRT_21, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_22, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_23, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_24, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_25, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_26, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_27, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_28, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_29, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_30, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_31, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_32, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[], [], 8) = 0
clone(child_stack=0xc208030000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD) = 1222
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
futex(0x4b5960, FUTEX_WAKE, 1)          = 1
rt_sigprocmask(SIG_SETMASK, ~[], [], 8) = 0
clone(child_stack=0xc20802e000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD) = 1223
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
futex(0x4b5e18, FUTEX_WAIT, 0, NULL)    = 0
rename("sample", "sample.1")            = 0
futex(0x4b5960, FUTEX_WAKE, 1)          = 1
exit_group(0)                           = ?
+++ exited with 0 +++

rename(2) 呼んでました。こちらからは以上です。

追記

社のチャットで実際どう言うコードなのよ?という話をしたら大変勉強になりました...

7
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7