看日志中的rename函数的一个报错信息:Invalid cross-device link,花几分钟google搜索之后确定不是问题,记录下相关排查和验证过程。
man手册里的资料:

EXDEV  The  links  named  by  new and old are on different file systems and the implementation does not support links between file systems.

返回EXDEV这个错误码是由于old和new位于不同的文件系统。为了验证这一观点,我从床底下搬出了我的上古时期的笔记本,恰好安装了centos7。

[root ~]#fdisk -l

磁盘 /dev/sdb:32.0 GB, 32017047552 字节,62533296 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节

WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion.

磁盘 /dev/sda:500.1 GB, 500107862016 字节,976773168 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 4096 字节
I/O 大小(最小/最佳):4096 字节 / 4096 字节
磁盘标签类型:gpt
Disk identifier: 8ED41EA3-6117-4C6B-BD8B-A526FD06A5F9


#         Start          End    Size  Type            Name
 1         2048       411647    200M  EFI System      EFI System Partition
 2       411648      2508799      1G  Microsoft basic
 3      2508800    976773119  464.6G  Linux LVM

磁盘 /dev/mapper/centos-root:53.7 GB, 53687091200 字节,104857600 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 4096 字节
I/O 大小(最小/最佳):4096 字节 / 4096 字节


磁盘 /dev/mapper/centos-swap:4160 MB, 4160749568 字节,8126464 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 4096 字节
I/O 大小(最小/最佳):4096 字节 / 4096 字节


磁盘 /dev/mapper/centos-home:441.0 GB, 440968151040 字节,861265920 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 4096 字节
I/O 大小(最小/最佳):4096 字节 / 4096 字节

mount执行部分结果:

/dev/mapper/centos-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
/dev/mapper/centos-home on /home type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

所以我们在home目录下创建一个example文件,随便echo进去一些内容,然后创建目录/root/workspace,编译执行如下程序:

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{
    int status;
    status = rename("/home/example", "/root/workspace/example");

    printf("%s\n",strerror(errno));
    return 0;
}

执行结果:

[root workspace]#./rename
Invalid cross-device link

将old和new都修改为在/root/目录下,可以移动文件成功,由此也验证了man手册中的说明。解决方法是如果rename失败,则尝试copy然后删除原文件。