mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-08-02 15:31:12 +00:00
Merge pull request #174 from dsheets/transfused-prepare-mounts
transfused: introduce automatic mount point preparation
This commit is contained in:
commit
b6765bb5cd
@ -4,10 +4,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@ -438,6 +440,82 @@ void start_writer(connection_t * connection, int fuse) {
|
|||||||
connection->mount_point);
|
connection->mount_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * alloc_dirname(connection_t * conn, char * path) {
|
||||||
|
size_t len = strlen(path) + 1;
|
||||||
|
char * input = must_malloc("alloc_dirname input", len);
|
||||||
|
char * output = must_malloc("alloc_dirname output", len);
|
||||||
|
char * dir;
|
||||||
|
strlcpy(input, path, len);
|
||||||
|
|
||||||
|
dir = dirname(input);
|
||||||
|
if (dir == NULL)
|
||||||
|
die(1, conn->params, "", "Couldn't get dirname of %s: ", path);
|
||||||
|
strcpy(output, dir);
|
||||||
|
|
||||||
|
free(input);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mkdir_p(connection_t * conn, char * path) {
|
||||||
|
char * parent;
|
||||||
|
|
||||||
|
if (mkdir(path, 0700)) switch (errno) {
|
||||||
|
case ENOENT:
|
||||||
|
parent = alloc_dirname(conn, path);
|
||||||
|
mkdir_p(conn, parent);
|
||||||
|
free(parent);
|
||||||
|
if (mkdir(path, 0700))
|
||||||
|
die(1, conn->params, "", "Couldn't create directory %s: ", path);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die(1, conn->params, "", "Couldn't create directory %s: ", path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_next_child_ok(connection_t * conn, DIR * dir) {
|
||||||
|
struct dirent * child;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
child = readdir(dir);
|
||||||
|
if (child == NULL) {
|
||||||
|
if (errno != 0)
|
||||||
|
die(1, conn->params, "", "Couldn't read mount point %s: ",
|
||||||
|
conn->mount_point);
|
||||||
|
else return 0;
|
||||||
|
} else
|
||||||
|
if (strcmp(".", child->d_name) != 0 && strcmp("..", child->d_name) != 0)
|
||||||
|
die(1, conn->params, NULL, "Couldn't mount on %s: %s exists",
|
||||||
|
conn->mount_point, child->d_name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The leaf may exist but must be empty. Any proper path prefix may exist.
|
||||||
|
void prepare_mount_point(connection_t * conn) {
|
||||||
|
DIR * dir;
|
||||||
|
char * mount_point = conn->mount_point;
|
||||||
|
|
||||||
|
dir = opendir(mount_point);
|
||||||
|
if (dir != NULL) {
|
||||||
|
if (is_next_child_ok(conn, dir))
|
||||||
|
if (is_next_child_ok(conn, dir)) {
|
||||||
|
if (is_next_child_ok(conn, dir))
|
||||||
|
die(1, conn->params, "", "Couldn't mount on %s: not empty",
|
||||||
|
mount_point);
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
if (closedir(dir))
|
||||||
|
die(1, conn->params, "", "Couldn't close mount point %s: ", mount_point);
|
||||||
|
} else {
|
||||||
|
switch (errno) {
|
||||||
|
case ENOENT: break;
|
||||||
|
default:
|
||||||
|
die(1, conn->params, "", "Couldn't open mount point %s: ", mount_point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir_p(conn, mount_point);
|
||||||
|
}
|
||||||
|
|
||||||
void * mount_connection(connection_t * conn) {
|
void * mount_connection(connection_t * conn) {
|
||||||
int optc;
|
int optc;
|
||||||
char ** optv;
|
char ** optv;
|
||||||
@ -451,6 +529,8 @@ void * mount_connection(connection_t * conn) {
|
|||||||
|
|
||||||
optv = read_opts(conn, buf);
|
optv = read_opts(conn, buf);
|
||||||
|
|
||||||
|
prepare_mount_point(conn);
|
||||||
|
|
||||||
for (optc = 0; optv[optc] != NULL; optc++) {}
|
for (optc = 0; optv[optc] != NULL; optc++) {}
|
||||||
|
|
||||||
fuse = get_fuse_sock(conn, optc, optv);
|
fuse = get_fuse_sock(conn, optc, optv);
|
||||||
|
Loading…
Reference in New Issue
Block a user