それはまあ、そうだろうとは思うのだが、本当にそうか(すなわちアトミックにファイル操作するのか)を確認した。
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)
呼んでました。こちらからは以上です。
追記
社のチャットで実際どう言うコードなのよ?という話をしたら大変勉強になりました...