Добавление нового Syscall для копирования файла в Linux-6.9.8, но «не удалось получить исходный файл статистики» ⇐ Linux
-
Anonymous
Добавление нового Syscall для копирования файла в Linux-6.9.8, но «не удалось получить исходный файл статистики»
Отредактированное ядро: Linux 6.9.8 < /p>
Машина для здания: AMD 9950x, Debian 12, Linux 6.1.0 < /p>
коды
kernel/sys.c
# codes above are omitted.
#endif /* CONFIG_COMPAT */
SYSCALL_DEFINE0(mycall) {
printk(KERN_INFO "Hello Linux 6.9.8 by Konrad\n");
return 0;
}
SYSCALL_DEFINE2(mycopy, const char __user *, s_file, const char __user *, t_file) {
struct kstat k_buf;
char copy_buf[1024];
char s_filename[256], t_filename[256];
struct file *read_file = NULL, *write_file = NULL;
long read_num;
/* Get source and target file name */
read_num = strncpy_from_user(s_filename, s_file, sizeof(s_filename));
if (read_num < 0 || read_num >= sizeof(s_filename)) {
printk(KERN_ERR "Failed to copy source filename from user space\n");
return read_num < 0 ? read_num : -ENAMETOOLONG;
}
read_num = strncpy_from_user(t_filename, t_file, sizeof(t_filename));
if (read_num < 0 || read_num >= sizeof(t_filename)) {
printk(KERN_ERR "Failed to copy target filename from user space\n");
return read_num < 0 ? read_num : -ENAMETOOLONG;
}
/* Print file paths */
printk(KERN_INFO "Source file: %s\n", s_filename);
printk(KERN_INFO "Target file: %s\n", t_filename);
/* Get source file mode */
if (vfs_stat(s_filename, &k_buf) != 0) {
printk(KERN_ERR "Failed to stat source file: %s\n", s_filename);
return -ENOENT;
}
/* Open files */
read_file = filp_open(s_filename, O_RDONLY, 0);
if (IS_ERR(read_file)) {
printk(KERN_ERR "Failed to open source file: %ld\n", PTR_ERR(read_file));
return PTR_ERR(read_file);
}
write_file = filp_open(t_filename, O_WRONLY | O_CREAT | O_TRUNC, k_buf.mode);
if (IS_ERR(write_file)) {
printk(KERN_ERR "Failed to open target file: %ld\n", PTR_ERR(write_file));
filp_close(read_file, NULL);
return PTR_ERR(write_file);
}
/* Do copy */
for (;;) {
read_num = kernel_read(read_file, copy_buf, sizeof(copy_buf), &read_file->f_pos);
if (read_num < 0) {
printk(KERN_ERR "Failed to read from source file: %ld\n", read_num);
filp_close(read_file, NULL);
filp_close(write_file, NULL);
return read_num;
} else if (read_num == 0)
break;
kernel_write(write_file, copy_buf, read_num, &write_file->f_pos);
}
filp_close(read_file, NULL);
filp_close(write_file, NULL);
return 0;
}
Arch/x86/Entry/syscalls/syscall_64.tbl
< /p>
ошибка < /h2>
Первый Syscall myCall (462) работает хорошо, но вторая mycopy (463) для копирования файлов не работала с кодами тестирования ниже:
#include
#include
#include
#include
#include
#define MYCOPY_SYSCALL 463
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(EXIT_FAILURE);
}
if (chdir("/usr/src/syscall") != 0) {
perror("Failed to change directory");
exit(EXIT_FAILURE);
}
const char *src_file = argv[1];
const char *dest_file = argv[2];
printf("Source file: %s\n", src_file);
printf("Destination file: %s\n", dest_file);
long result = syscall(MYCOPY_SYSCALL, src_file, dest_file);
if (result == -1) {
printf("Error: errno=%d\n", errno);
perror("Error in mycopy syscall");
exit(EXIT_FAILURE);
} else {
printf("File copied successfully from %s to %s\n", src_file, dest_file);
}
return 0;
}
Дополнительная информация о запуске указана в IMG:
и разрешения для/usr - 777 рекурсивно.
Согласно информации об ошибке, это может быть vfs_stat () в ядре/sys.c , но я не знаю причину, кто -нибудь может помочь?
/* Get source file mode */
if (vfs_stat(s_filename, &k_buf) != 0) {
printk(KERN_ERR "Failed to stat source file: %s\n", s_filename);
return -ENOENT;
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... tat-source
Отредактированное ядро: Linux 6.9.8 < /p>
Машина для здания: AMD 9950x, Debian 12, Linux 6.1.0 < /p>
коды
kernel/sys.c
# codes above are omitted.
#endif /* CONFIG_COMPAT */
SYSCALL_DEFINE0(mycall) {
printk(KERN_INFO "Hello Linux 6.9.8 by Konrad\n");
return 0;
}
SYSCALL_DEFINE2(mycopy, const char __user *, s_file, const char __user *, t_file) {
struct kstat k_buf;
char copy_buf[1024];
char s_filename[256], t_filename[256];
struct file *read_file = NULL, *write_file = NULL;
long read_num;
/* Get source and target file name */
read_num = strncpy_from_user(s_filename, s_file, sizeof(s_filename));
if (read_num < 0 || read_num >= sizeof(s_filename)) {
printk(KERN_ERR "Failed to copy source filename from user space\n");
return read_num < 0 ? read_num : -ENAMETOOLONG;
}
read_num = strncpy_from_user(t_filename, t_file, sizeof(t_filename));
if (read_num < 0 || read_num >= sizeof(t_filename)) {
printk(KERN_ERR "Failed to copy target filename from user space\n");
return read_num < 0 ? read_num : -ENAMETOOLONG;
}
/* Print file paths */
printk(KERN_INFO "Source file: %s\n", s_filename);
printk(KERN_INFO "Target file: %s\n", t_filename);
/* Get source file mode */
if (vfs_stat(s_filename, &k_buf) != 0) {
printk(KERN_ERR "Failed to stat source file: %s\n", s_filename);
return -ENOENT;
}
/* Open files */
read_file = filp_open(s_filename, O_RDONLY, 0);
if (IS_ERR(read_file)) {
printk(KERN_ERR "Failed to open source file: %ld\n", PTR_ERR(read_file));
return PTR_ERR(read_file);
}
write_file = filp_open(t_filename, O_WRONLY | O_CREAT | O_TRUNC, k_buf.mode);
if (IS_ERR(write_file)) {
printk(KERN_ERR "Failed to open target file: %ld\n", PTR_ERR(write_file));
filp_close(read_file, NULL);
return PTR_ERR(write_file);
}
/* Do copy */
for (;;) {
read_num = kernel_read(read_file, copy_buf, sizeof(copy_buf), &read_file->f_pos);
if (read_num < 0) {
printk(KERN_ERR "Failed to read from source file: %ld\n", read_num);
filp_close(read_file, NULL);
filp_close(write_file, NULL);
return read_num;
} else if (read_num == 0)
break;
kernel_write(write_file, copy_buf, read_num, &write_file->f_pos);
}
filp_close(read_file, NULL);
filp_close(write_file, NULL);
return 0;
}
Arch/x86/Entry/syscalls/syscall_64.tbl
< /p>
ошибка < /h2>
Первый Syscall myCall (462) работает хорошо, но вторая mycopy (463) для копирования файлов не работала с кодами тестирования ниже:
#include
#include
#include
#include
#include
#define MYCOPY_SYSCALL 463
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(EXIT_FAILURE);
}
if (chdir("/usr/src/syscall") != 0) {
perror("Failed to change directory");
exit(EXIT_FAILURE);
}
const char *src_file = argv[1];
const char *dest_file = argv[2];
printf("Source file: %s\n", src_file);
printf("Destination file: %s\n", dest_file);
long result = syscall(MYCOPY_SYSCALL, src_file, dest_file);
if (result == -1) {
printf("Error: errno=%d\n", errno);
perror("Error in mycopy syscall");
exit(EXIT_FAILURE);
} else {
printf("File copied successfully from %s to %s\n", src_file, dest_file);
}
return 0;
}
Дополнительная информация о запуске указана в IMG:
и разрешения для/usr - 777 рекурсивно.
Согласно информации об ошибке, это может быть vfs_stat () в ядре/sys.c , но я не знаю причину, кто -нибудь может помочь?
/* Get source file mode */
if (vfs_stat(s_filename, &k_buf) != 0) {
printk(KERN_ERR "Failed to stat source file: %s\n", s_filename);
return -ENOENT;
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... tat-source
Мобильная версия