From 870d6aa5d942ef941809594f1c971c1e1f067d09 Mon Sep 17 00:00:00 2001 From: seantywork Date: Thu, 6 Nov 2025 05:05:25 +0000 Subject: [PATCH] okay --- kchr-store/2025-1105.xyz.md | 159 +++++++++++++++++++++++++++++++++++- kchr-store/chr_store.c | 8 +- kchr-store/user/Makefile | 2 +- kchr-store/user/u.c | 151 +++++++++++++++++++++++----------- 4 files changed, 269 insertions(+), 51 deletions(-) diff --git a/kchr-store/2025-1105.xyz.md b/kchr-store/2025-1105.xyz.md index 4e768b5..1897465 100644 --- a/kchr-store/2025-1105.xyz.md +++ b/kchr-store/2025-1105.xyz.md @@ -1 +1,158 @@ -# \ No newline at end of file +# struct file_operations + +```c + struct file_operations { + struct module *owner; + loff_t (*llseek) (struct file *, loff_t, int); + ssize_t (*read) (struct file *, char *, size_t, loff_t *); + ssize_t (*write) (struct file *, const char *, size_t, loff_t *); + int (*readdir) (struct file *, void *, filldir_t); + unsigned int (*poll) (struct file *, struct poll_table_struct *); + int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); + int (*mmap) (struct file *, struct vm_area_struct *); + int (*open) (struct inode *, struct file *); + int (*flush) (struct file *); + int (*release) (struct inode *, struct file *); + int (*fsync) (struct file *, struct dentry *, int datasync); + int (*fasync) (int, struct file *, int); + int (*lock) (struct file *, int, struct file_lock *); + ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, + loff_t *); + ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, + loff_t *); + }; + +``` + + +# registering file operations + +```c +static struct file_operations fops = { + .llseek = device_llseek, + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; +``` + +# +```shell + +thy@ubuntu24-server:~/linuxyz/kchr-store$ sudo ./dev_create.sh +dev node created +./user/chr_store +``` + +```shell +[ +39.686846] chr_store: dev_major number: 239: init + +``` +# +```shell +thy@ubuntu24-server:~/linuxyz/kchr-store/user$ sudo ./u.out "hello from the other +side" +cmd: [w/q] +main: file opened +thread: failed to open: -1 +thread: failed to open: -1 + +``` + +```shell +[Nov 6 05:01] file opened: 1 +[ +1.000207] not possible to open: already occupied: 1 +[ +1.000239] not possible to open: already occupied: 1 +[ +1.000297] not possible to open: already occupied: 1 +[ +1.000664] not possible to open: already occupied: 1 +[ +1.000504] not possible to open: already occupied: 1 +[ +1.000295] not possible to open: already occupied: 1 + +``` + +# + +```shell +q +main: quit +thread: closed file +thread: closed file +``` + +```shell +[ +1.000319] not possible to open: already occupied: 1 +[ +0.634617] file closed: 0 +[ +0.365655] file opened: 1 +[ +0.000102] chr_store: seek: 2 +[ +0.000007] chr_store: seek: 0 +[ +0.000018] file closed: 0 +[ +0.000046] file opened: 1 +[ +0.000013] chr_store: seek: 2 +[ +0.000004] chr_store: seek: 0 +[ +0.000006] file closed: 0 + +``` + +# + +```shell + +w +target write size: 25 +main: file closed +main: file opened +thread: failed to open: +``` + +```shell +[ +1.000297] not possible to open: already occupied: 1 +[ +0.886453] chr_store: w length: 25 +[ +0.000059] file closed: 0 +[ +0.000043] file opened: 1 +[ +0.113658] not possible to open: already occupied: 1 + +``` + +# + +```shell +q +main: quit +read: 25: hello from the other side +thread: closed file +read: 25: hello from the other side +thread: closed file + +``` + +```shell + +[ +12.217694] file opened: 1 +[Nov 6 05:04] not possible to open: already occupied: 1 +[ +1.000287] not possible to open: already occupied: 1 +[ +1.000138] not possible to open: already occupied: 1 +[ +0.151953] file closed: 0 +[ +0.848280] file opened: 1 +[ +0.000044] chr_store: seek: 2 +[ +0.000008] chr_store: seek: 0 +[ +0.000105] chr_store: r length: 4096 +[ +0.000038] file closed: 0 +[ +0.000025] file opened: 1 +[ +0.000016] chr_store: seek: 2 +[ +0.000005] chr_store: seek: 0 +[ +0.000006] chr_store: r length: 4096 +[ +0.000014] file closed: 0 + +``` + +# + +```shell +thy@ubuntu24-server:~/linuxyz/kchr-store$ sudo ./dev_destroy.sh +dev node destroyed + +``` +```shell +[ +45.326173] chr_store: dev_major: 239: gone +``` \ No newline at end of file diff --git a/kchr-store/chr_store.c b/kchr-store/chr_store.c index 103f3a8..a4815aa 100644 --- a/kchr-store/chr_store.c +++ b/kchr-store/chr_store.c @@ -19,9 +19,11 @@ static __u8* msg = NULL; static int device_open(struct inode *inode, struct file *filp){ if (device_open_counter){ + printk(KERN_INFO "not possible to open: already occupied: %d\n", device_open_counter); return -EBUSY; } device_open_counter++; + printk(KERN_INFO "file opened: %d\n", device_open_counter); try_module_get(THIS_MODULE); return SUCCESS; } @@ -29,6 +31,7 @@ static int device_open(struct inode *inode, struct file *filp){ static int device_release(struct inode *inode, struct file *filp){ device_open_counter--; + printk(KERN_INFO "file closed: %d\n", device_open_counter); module_put(THIS_MODULE); return SUCCESS; } @@ -97,6 +100,7 @@ static ssize_t device_write(struct file *filp, const char *buf, size_t len, loff static loff_t device_llseek(struct file* filp, loff_t offset, int whence){ loff_t retval = 0; + printk(KERN_INFO "chr_store: seek: %d\n", whence); if(blk_count == 0){ return 0; } @@ -132,7 +136,7 @@ static int __init init_chr_store(void){ printk(KERN_ALERT "registering char device failed with %d\n", dev_major); return dev_major; } - printk(KERN_INFO "dev_major number: %d\n", dev_major); + printk(KERN_INFO "chr_store: dev_major number: %d: init\n", dev_major); return SUCCESS; } @@ -142,7 +146,7 @@ static void __exit exit_chr_store(void){ if(msg != NULL){ kfree(msg); } - printk(KERN_INFO "dev_major: %d: gone\n", dev_major); + printk(KERN_INFO "chr_store: dev_major: %d: gone\n", dev_major); } module_init(init_chr_store); diff --git a/kchr-store/user/Makefile b/kchr-store/user/Makefile index 67b995c..623efa2 100644 --- a/kchr-store/user/Makefile +++ b/kchr-store/user/Makefile @@ -1,4 +1,4 @@ all: - gcc -Wall -o u.out u.c + gcc -g -Wall -o u.out u.c -lpthread clean: rm -rf *.out *.o \ No newline at end of file diff --git a/kchr-store/user/u.c b/kchr-store/user/u.c index 1e8a866..142438e 100644 --- a/kchr-store/user/u.c +++ b/kchr-store/user/u.c @@ -1,65 +1,122 @@ #include #include #include +#include +#include #define DEV_NAME "./chr_store" -void print_help(){ - printf("r $number: reads $number of characters from the beginning\n"); - printf("w \"$message\": write $message to the file\n"); +int open_file(FILE** f){ + *f = fopen(DEV_NAME, "r+"); + if(*f == NULL){ + return -1; + } + return 0; } -int main(int argc, char** argv){ +int read_from_file(FILE* f){ + long fsize = 0; + if(fseek(f, 0L, SEEK_END) == 0){ + fsize = ftell(f); + if(fsize < 0){ + return -1; + } + if(fseek(f, 0L, SEEK_SET) != 0){ + return -2; + } + } else { + return -3; + } + if(fsize == 0){ + return 0; + } + char* buff = calloc(fsize, sizeof(char)); + int n = fread(buff, sizeof(char), fsize, f); + printf("read: %d: %s\n", n, buff); + free(buff); + return n; +} +int write_to_file(FILE* f, char* msg){ + int arglen = strlen(msg); + printf("target write size: %d\n", arglen); + int n = fwrite(msg, sizeof(char), arglen, f); + return n; +} + +void close_file(FILE* f){ + fclose(f); +} + +void* try_open_and_read(void* val){ + int* keepalive = (int*)val; + int res; FILE* f = NULL; - int number = 0; - char* buff = NULL; - if(argc != 3){ - print_help(); - return -1; + while(*keepalive){ + sleep(1); + if((res = open_file(&f)) < 0){ + printf("thread: failed to open: %d\n", res); + continue; + } + if((res = read_from_file(f)) < 0){ + printf("thread: failed to read: %d\n", res); + } + close_file(f); + printf("thread: closed file\n"); } - f = fopen(DEV_NAME, "r+"); - if(f == NULL){ - printf("failed to open file: %s\n", DEV_NAME); - return -1; + if((res = open_file(&f)) < 0){ + printf("thread: failed to open: %d\n", res); + pthread_exit(NULL); } - if(strcmp(argv[1], "r") == 0){ - long fsize = 0; - sscanf(argv[2], "%d", &number); - if(fseek(f, 0L, SEEK_END) == 0){ - fsize = ftell(f); - if(fsize < 0){ - printf("failed to seek size\n"); - goto out; - } - if(fseek(f, 0L, SEEK_SET) != 0){ - printf("failed to reset pos\n"); + if((res = read_from_file(f)) < 0){ + printf("thread: failed to read: %d\n", res); + } + close_file(f); + printf("thread: closed file\n"); + *keepalive = 1; + pthread_exit(NULL); +} + +int main(int argc, char** argv){ + + FILE* f = NULL; + int keepalive = 1; + pthread_t tid; + pthread_create(&tid, NULL, try_open_and_read, (void*)&keepalive); + printf("cmd: [w/q] \n"); + while(keepalive){ + int res; + if((res = open_file(&f)) < 0){ + printf("main: failed to open file: %d\n", res); + continue; + } + printf("main: file opened\n"); + char cmd; + scanf(" %c", &cmd); + do{ + if(cmd == 'w'){ + if(argc != 2){ + printf("main: w option needs message argument from command line\n"); + break; + } + if((res = write_to_file(f, argv[1])) < 0){ + printf("main: failed to write to file: %d\n", res); + } + } else if (cmd == 'q') { + printf("main: quit\n"); + keepalive = 0; + close_file(f); goto out; + } else { + printf("invalid argument: %c\n", cmd); } - } else { - printf("failed to seek eof\n"); - goto out; - } - if(fsize == 0){ - printf("nothing to read\n"); - return 0; - } - printf("current chr_storage size: %ld\n", fsize); - buff = calloc(fsize, sizeof(char)); - int n = fread(buff, sizeof(char), number, f); - printf("read: %d: %s\n", n, buff); - free(buff); - } else if(strcmp(argv[1], "w") == 0){ - int arglen = strlen(argv[2]); - int n = fwrite(argv[2], sizeof(char), arglen, f); - printf("write: %d\n", n); - } else { - printf("invalid argument: %s\n", argv[1]); - print_help(); - return -1; + }while(0); + close_file(f); + printf("main: file closed\n"); } out: - fclose(f); - + while(keepalive == 0){ + sleep(1); + } return 0; } \ No newline at end of file -- 2.43.0