add multithreading
This commit is contained in:
parent
724b0bb5f6
commit
81e60ce1cc
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
test
|
test
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
.vscode
|
.vscode
|
||||||
.cache
|
.cache
|
||||||
|
build
|
||||||
2
Makefile
2
Makefile
@ -42,6 +42,8 @@ $(OBJ_PATH)/%.o: $(SRC_PATH)/%.c
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
@install -vpm 755 -o root -g root $(BIN_PATH)/$(BIN_NAME) /usr/bin/
|
@install -vpm 755 -o root -g root $(BIN_PATH)/$(BIN_NAME) /usr/bin/
|
||||||
|
@install -vpm 644 -o root -g root pupes-backup.service /etc/systemd/system/
|
||||||
|
useradd -m -d /srv/backup -r -s /usr/sbin/nologin pupes_backup
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -fr build
|
rm -fr build
|
||||||
|
|||||||
Binary file not shown.
BIN
build/obj/main.o
BIN
build/obj/main.o
Binary file not shown.
12
pupes-backup.service
Normal file
12
pupes-backup.service
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=ssh port forwarding service
|
||||||
|
After=network.target
|
||||||
|
StartLimitIntervalSec=0
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=pupes_backup
|
||||||
|
WorkingDirectory=/srv/backup
|
||||||
|
ExecStart=/usr/bin/pupes-backup-server /srv/backup 192.168.1.213
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
63
src/main.c
63
src/main.c
@ -14,20 +14,36 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/sendfile.h>
|
#include <sys/sendfile.h>
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#define ALLOWED_IP "192.168.1.213"
|
|
||||||
#define MAX_FILE_SIZE_G 100
|
#define MAX_FILE_SIZE_G 100
|
||||||
#define MAX_FILE_SIZE (size_t)MAX_FILE_SIZE_G*1073741824
|
#define MAX_FILE_SIZE (size_t)MAX_FILE_SIZE_G*1073741824
|
||||||
|
|
||||||
#define READ_BUFFER_SIZE 32768 // 256K
|
#define READ_BUFFER_SIZE 134217728 // 256M
|
||||||
|
|
||||||
const char* filename_base = "backup";
|
const char* filename_base = "backup";
|
||||||
|
|
||||||
|
struct thread_context {
|
||||||
|
int fd;
|
||||||
|
char* buff;
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
_Bool write_thread_done = 1;
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
void* thread_function(void* arg) {
|
||||||
|
struct thread_context* context = arg;
|
||||||
|
if (write(context->fd, context->buff,context->count) == -1) {
|
||||||
|
fprintf(stderr, YELLOW"["RED"CRITICAL"YELLOW"]"RESET" Error: %s, when writing failed file may be corupted\n", strerror(errno));
|
||||||
|
}
|
||||||
|
write_thread_done = 1;
|
||||||
|
free(context->buff);
|
||||||
|
free(context);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc < 2) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage:\n%s [BACKUP DIRECTORY]\n", argv[0]);
|
fprintf(stderr, "Usage:\n%s [BACKUP DIRECTORY] [ALLOWED IP]\n", argv[0]);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
int client_fd;
|
int client_fd;
|
||||||
@ -78,7 +94,7 @@ int main(int argc, char* argv[]) {
|
|||||||
inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, INET_ADDRSTRLEN);
|
||||||
|
|
||||||
|
|
||||||
if (strcmp(client_ip, ALLOWED_IP) == 0) {
|
if (strcmp(client_ip, argv[2]) == 0) {
|
||||||
printf("Accepted connection from %s\n", client_ip);
|
printf("Accepted connection from %s\n", client_ip);
|
||||||
const time_t unix_time = time(NULL);
|
const time_t unix_time = time(NULL);
|
||||||
|
|
||||||
@ -99,30 +115,41 @@ int main(int argc, char* argv[]) {
|
|||||||
ssize_t bytes_transferred;
|
ssize_t bytes_transferred;
|
||||||
size_t receved_this_read_cicle = SIZE_MAX;
|
size_t receved_this_read_cicle = SIZE_MAX;
|
||||||
size_t total_received = 0;
|
size_t total_received = 0;
|
||||||
char* read_buffer = malloc(READ_BUFFER_SIZE);
|
pthread_t write_thread;
|
||||||
|
|
||||||
while (receved_this_read_cicle != 0 && total_received < MAX_FILE_SIZE){
|
while (receved_this_read_cicle != 0 && total_received < MAX_FILE_SIZE){
|
||||||
|
char* read_buffer = malloc(READ_BUFFER_SIZE);
|
||||||
receved_this_read_cicle = 0;
|
receved_this_read_cicle = 0;
|
||||||
while ((bytes_transferred = read(client_fd, read_buffer, READ_BUFFER_SIZE - receved_this_read_cicle)) > 0) {
|
while ((bytes_transferred = read(client_fd, read_buffer+receved_this_read_cicle, READ_BUFFER_SIZE - receved_this_read_cicle)) > 0) {
|
||||||
if (bytes_transferred == -1) {
|
if (bytes_transferred == -1) {
|
||||||
fprintf(stderr, YELLOW"["RED"CRITICAL"YELLOW"]"RESET" Error: %s, when receving file: %s failed file may be corupted\n", strerror(errno) ,full_filename_path);
|
fprintf(stderr, YELLOW"["RED"CRITICAL"YELLOW"]"RESET" Error: %s, when receving file: %s failed file may be corupted\n", strerror(errno) ,full_filename_path);
|
||||||
goto client_cleanup;
|
goto client_cleanup;
|
||||||
}
|
}
|
||||||
receved_this_read_cicle += bytes_transferred;
|
receved_this_read_cicle += bytes_transferred;
|
||||||
}
|
}
|
||||||
if (receved_this_read_cicle == 0) {break;}
|
if (receved_this_read_cicle == 0) {break;}
|
||||||
|
|
||||||
total_received += receved_this_read_cicle;
|
total_received += receved_this_read_cicle;
|
||||||
|
|
||||||
if (write(savefile_fd, read_buffer, receved_this_read_cicle) == -1) {
|
if (!write_thread_done) {pthread_join(write_thread, NULL);}
|
||||||
fprintf(stderr, YELLOW"["RED"CRITICAL"YELLOW"]"RESET" Error: %s, when writing file: %s failed file may be corupted\n", strerror(errno) ,full_filename_path);
|
|
||||||
}}
|
|
||||||
client_cleanup:
|
|
||||||
|
|
||||||
|
{
|
||||||
|
struct thread_context* thread_context = malloc(sizeof(struct thread_context));
|
||||||
|
thread_context->buff = read_buffer;
|
||||||
|
thread_context->count = receved_this_read_cicle;
|
||||||
|
thread_context->fd = savefile_fd;
|
||||||
|
write_thread_done = 0;
|
||||||
|
if (pthread_create(&write_thread, NULL, thread_function, thread_context) != 0) {
|
||||||
|
perror("Failed to create write thread");
|
||||||
|
return 1;
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
client_cleanup:
|
||||||
|
if (!write_thread_done) {pthread_join(write_thread, NULL);};
|
||||||
printf("finished handling: %s\n",full_filename_path);
|
printf("finished handling: %s\n",full_filename_path);
|
||||||
free(read_buffer);
|
|
||||||
free(full_filename_path);
|
free(full_filename_path);
|
||||||
close(savefile_fd);
|
|
||||||
close(client_fd);
|
close(client_fd);
|
||||||
|
close(savefile_fd);
|
||||||
} else {
|
} else {
|
||||||
printf("Rejected connection from %s\n", client_ip);
|
printf("Rejected connection from %s\n", client_ip);
|
||||||
close(client_fd);
|
close(client_fd);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user