Re: [PATCH 0/7] orangefs uapi

From: martin
Date: Fri Jan 26 2018 - 14:15:10 EST


On Fri, Jan 26, 2018 at 02:07:10PM -0500, Martin Brandenburg wrote:
> I have also written a "fakecore" which does about the bare minimum to
> start up and respond to mount requests. I intend to use this as a
> vehicle for experimentation with fuzzing and testing performance through
> our kernel code without the rest of OrangeFS running.

#include <sys/ioctl.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "linux/include/uapi/linux/orangefs.h"

#define ORANGEFS_REQDEVICE_NAME "pvfs2-req"

struct downcall {
int32_t proto_ver;
int32_t magic;
int32_t tag;
struct orangefs_downcall_s d;
};

struct upcall {
int32_t proto_ver;
int32_t magic;
int32_t tag;
struct orangefs_upcall_s u;
};

static int mounted = 0;

int process_request(struct upcall *upcall, struct downcall *downcall)
{
struct stat sb;
switch (upcall->u.type) {
case ORANGEFS_VFS_OP_GETATTR:
downcall->d.resp.getattr.attributes.objtype =
ORANGEFS_TYPE_DIRECTORY;
return 0;
case ORANGEFS_VFS_OP_FS_MOUNT:
if (mounted) {
downcall->d.status = -(ORANGEFS_ERROR_BIT|EPERM);
return 0;
}
downcall->d.resp.fs_mount.fs_id = 1;
downcall->d.resp.fs_mount.id = mounted;
downcall->d.resp.fs_mount.root_khandle.u[0] = 1;
if (stat(".", &sb)) {
downcall->d.status = -(ORANGEFS_ERROR_BIT|errno);
return 0;
}
memcpy(downcall->d.resp.fs_mount.root_khandle.u, &sb.st_ino,
sizeof sb.st_ino);
mounted = 1;
return 0;
case ORANGEFS_VFS_OP_FS_UMOUNT:
mounted = 0;
return 0;
default:
downcall->d.status = -(ORANGEFS_ERROR_BIT|EPERM);
return 0;
}
}

int main(void)
{
int32_t magic, max_upsize, max_downsize;
struct downcall downcall;
struct upcall upcall;
int fd, upstream;

fd = open("/dev/" ORANGEFS_REQDEVICE_NAME, O_RDWR|O_NONBLOCK);
if (fd == -1) {
perror("open");
return 1;
}

if (ioctl(fd, ORANGEFS_DEV_GET_MAGIC, &magic)) {
perror("ioctl");
return 1;
}
if (ioctl(fd, ORANGEFS_DEV_GET_MAX_UPSIZE, &max_upsize)) {
perror("ioctl");
return 1;
}
if (ioctl(fd, ORANGEFS_DEV_GET_MAX_DOWNSIZE, &max_downsize)) {
perror("ioctl");
return 1;
}
if (ioctl(fd, ORANGEFS_DEV_UPSTREAM, &upstream)) {
perror("ioctl");
return 1;
}

printf("magic: %d\n", magic);
printf("max_upsize: %d, sizeof upcall: %d\n",
max_upsize, sizeof upcall);
printf("max_downsize: %d, sizeof downcall: %d\n",
max_downsize, sizeof downcall);
printf("upstream: %d\n", upstream);

while (1) {
int r;
r = read(fd, &upcall, sizeof upcall);
if (r == -1) {
if (errno == EAGAIN)
continue;
perror("read");
return 1;
} else if (r < sizeof upcall) {
fprintf(stderr, "short read\n");
return 1;
}
downcall.proto_ver = ORANGEFS_MINIMUM_USERSPACE_VERSION;
downcall.magic = upcall.magic;
downcall.tag = upcall.tag;
memset(&downcall.d, 0, sizeof downcall.d);
downcall.d.type = upcall.u.type;
downcall.d.status = 0;
printf("read tag type %d\n", upcall.tag, upcall.u.type);
if (process_request(&upcall, &downcall)) {
fprintf(stderr, "process_request failed\n");
return 1;
}
r = write(fd, &downcall, sizeof downcall);
if (r == -1) {
perror("write");
return 1;
} else if (r < sizeof downcall) {
perror("short write");
return 1;
}
printf("wrote tag %d status %d\n", downcall.tag,
downcall.d.status);
}

if (close(fd)) {
perror("close");
return 1;
}
return 0;
}