(not working) kludge to allow mountign with a single connection in BeOS (mount open()/close() twice).

Implement correct settings.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20995 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2007-05-03 14:40:42 +00:00
parent ac156738e9
commit 7f66887bc3

View File

@ -18,6 +18,12 @@
#define DEBUG 1 #define DEBUG 1
/* on the first open(), open ourselves for some seconds,
* to avoid trying to reconnect and failing on a 2nd open,
* as it happens with the python server.
*/
//#define MOUNT_KLUDGE
/* locking support */ /* locking support */
#ifdef __HAIKU__ #ifdef __HAIKU__
#include <kernel/lock.h> #include <kernel/lock.h>
@ -68,7 +74,8 @@ struct nbd_request_entry {
}; };
struct nbd_device { struct nbd_device {
char target[64]; // "ip:port" bool valid;
bool readonly;
struct sockaddr_in server; struct sockaddr_in server;
benaphore ben; benaphore ben;
vint32 refcnt; vint32 refcnt;
@ -77,6 +84,9 @@ struct nbd_device {
thread_id postoffice; thread_id postoffice;
uint64 size; uint64 size;
struct nbd_request_entry *reqs; struct nbd_request_entry *reqs;
#ifdef MOUNT_KLUDGE
int kludge;
#endif
}; };
typedef struct cookie { typedef struct cookie {
@ -103,6 +113,28 @@ KSOCKET_MODULE_DECL;
bool gDelayUnload = false; bool gDelayUnload = false;
#define BONE_TEARDOWN_DELAY 60000000 #define BONE_TEARDOWN_DELAY 60000000
#pragma mark ==== support ====
// move that to ksocket inlined
static int kinet_aton(const char *in, struct in_addr *addr)
{
int i;
unsigned long a;
uint32 inaddr = 0L;
const char *p = in;
for (i = 0; i < 4; i++) {
a = strtoul(p, &p, 10);
if (!p)
return -1;
inaddr = (inaddr >> 8) | ((a & 0x0ff) << 24);
*(uint32 *)addr = inaddr;
if (!*p)
return 0;
p++;
}
return 0;
}
#pragma mark ==== request manager ==== #pragma mark ==== request manager ====
status_t nbd_alloc_request(struct nbd_device *dev, struct nbd_request_entry **req, uint32 type, off_t from, size_t len, const char *data) status_t nbd_alloc_request(struct nbd_device *dev, struct nbd_request_entry **req, uint32 type, off_t from, size_t len, const char *data)
@ -383,11 +415,15 @@ static struct nbd_device nbd_devices[MAX_NBDS];
status_t nbd_open(const char *name, uint32 flags, cookie_t **cookie) { status_t nbd_open(const char *name, uint32 flags, cookie_t **cookie) {
status_t err; status_t err;
int32 refcnt;
#ifdef MOUNT_KLUDGE
int kfd;
#endif
struct nbd_device *dev = NULL; struct nbd_device *dev = NULL;
PRINT((DP ">%s(%s, %x, )\n", __FUNCTION__, name, flags)); PRINT((DP ">%s(%s, %x, )\n", __FUNCTION__, name, flags));
(void)name; (void)flags; (void)name; (void)flags;
dev = nbd_find_device(name); dev = nbd_find_device(name);
if (!dev) if (!dev || !dev->valid)
return ENOENT; return ENOENT;
err = ENOMEM; err = ENOMEM;
*cookie = (void*)malloc(sizeof(cookie_t)); *cookie = (void*)malloc(sizeof(cookie_t));
@ -403,8 +439,23 @@ status_t nbd_open(const char *name, uint32 flags, cookie_t **cookie) {
err = nbd_connect(dev); err = nbd_connect(dev);
if (err) if (err)
goto err2; goto err2;
dev->refcnt++; refcnt = dev->refcnt++;
#ifdef MOUNT_KLUDGE
kfd = dev->kludge;
dev->kludge = -1;
#endif
benaphore_unlock(&dev->ben); benaphore_unlock(&dev->ben);
#ifdef MOUNT_KLUDGE
if (refcnt == 0) {
char buf[32];
sprintf(buf, "/dev/%s", name);
dev->kludge = open(buf, O_RDONLY);
} else if (kfd) {
close(kfd);
}
#endif
return B_OK; return B_OK;
err2: err2:
@ -419,6 +470,9 @@ err0:
status_t nbd_close(cookie_t *cookie) { status_t nbd_close(cookie_t *cookie) {
struct nbd_device *dev = cookie->dev; struct nbd_device *dev = cookie->dev;
status_t err; status_t err;
#ifdef MOUNT_KLUDGE
int kfd = -1;
#endif
PRINT((DP ">%s(%d)\n", __FUNCTION__, WHICH(cookie->dev))); PRINT((DP ">%s(%d)\n", __FUNCTION__, WHICH(cookie->dev)));
err = benaphore_lock(&dev->ben); err = benaphore_lock(&dev->ben);
@ -426,8 +480,18 @@ status_t nbd_close(cookie_t *cookie) {
return err; return err;
// XXX: do something ? // XXX: do something ?
#ifdef MOUNT_KLUDGE
kfd = dev->kludge;
dev->kludge = -1;
#endif
benaphore_unlock(&dev->ben); benaphore_unlock(&dev->ben);
#ifdef MOUNT_KLUDGE
if (kfd > -1) {
close(kfd);
}
#endif
return B_OK; return B_OK;
} }
@ -615,12 +679,19 @@ init_driver (void)
void *handle; void *handle;
PRINT((DP ">%s()\n", __FUNCTION__)); PRINT((DP ">%s()\n", __FUNCTION__));
handle = load_driver_settings(DRV);
if (handle == NULL)
return ENOENT;
// XXX: test for boot args ?
err = ksocket_init(); err = ksocket_init();
if (err < B_OK) if (err < B_OK)
return err; return err;
for (i = 0; i < MAX_NBDS; i++) { for (i = 0; i < MAX_NBDS; i++) {
memset(nbd_devices[i].target, 0, 64); nbd_devices[i].valid = false;
nbd_devices[i].readonly = false;
err = benaphore_init(&nbd_devices[i].ben, "nbd lock"); err = benaphore_init(&nbd_devices[i].ben, "nbd lock");
if (err < B_OK) if (err < B_OK)
return err; // XXX return err; // XXX
@ -630,48 +701,44 @@ init_driver (void)
nbd_devices[i].postoffice = -1; nbd_devices[i].postoffice = -1;
nbd_devices[i].size = 0LL; nbd_devices[i].size = 0LL;
nbd_devices[i].reqs = NULL; nbd_devices[i].reqs = NULL;
#ifdef MOUNT_KLUDGE
nbd_devices[i].kludge = -1;
#endif
nbd_name[i] = malloc(DEVICE_NAME_MAX); nbd_name[i] = malloc(DEVICE_NAME_MAX);
if (nbd_name[i] == NULL) if (nbd_name[i] == NULL)
break; break;
sprintf(nbd_name[i], DEVICE_FMT, i); sprintf(nbd_name[i], DEVICE_FMT, i);
/* XXX: default init */
nbd_devices[i].server.sin_len = sizeof(struct sockaddr_in);
nbd_devices[i].server.sin_family = AF_INET;
nbd_devices[i].server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
nbd_devices[i].server.sin_port = htons(1337 + i);
} }
nbd_name[i] = NULL; nbd_name[i] = NULL;
handle = load_driver_settings(DRV); for (i = 0; i < MAX_NBDS; i++) {
if (handle) { driver_settings *settings = get_driver_settings(handle);
for (i = 0; i < MAX_NBDS; i++) { driver_parameter *p;
char keyname[10]; char keyname[10];
char *v; char *v;
sprintf(keyname, "nbd%d", i); sprintf(keyname, "%d", i);
v = get_driver_parameter(handle, keyname, NULL, NULL); for (j = 0; j < settings->parameter_count; j++)
/* should be "ip:port" */ if (!strcmp(settings->parameters[j].name, keyname))
// XXX: test p = &settings->parameters[j];
if (v || 1) { if (!p)
//strncpy(nbd_devices[i].target, v, 64); continue;
//XXX:TEST for (j = 0; j < p->parameter_count; j++) {
//strncpy(nbd_devices[i].target, "127.0.0.1:1337", 64); if (!strcmp(p->parameters[j].name, "readonly"))
//XXX:parse it nbd_devices[i].readonly = true;
if (!strcmp(p->parameters[j].name, "server")) {
if (p->parameters[j].value_count < 2)
continue;
nbd_devices[i].server.sin_len = sizeof(struct sockaddr_in); nbd_devices[i].server.sin_len = sizeof(struct sockaddr_in);
nbd_devices[i].server.sin_family = AF_INET; nbd_devices[i].server.sin_family = AF_INET;
nbd_devices[i].server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); kinet_aton(p->parameters[j].values[0], &nbd_devices[i].server.sin_addr);
nbd_devices[i].server.sin_port = htons(1337 + i); nbd_devices[i].server.sin_port = htons(atoi(p->parameters[j].values[1]));
nbd_devices[i].valid = true;
} }
} }
/*should parse as a tree:
settings = get_driver_settings(handle);
for (i = 0; i < settings->parameter_count; i++) {
}
*/
unload_driver_settings(handle);
} }
unload_driver_settings(handle);
return B_OK; return B_OK;
} }