-.PHONY: default clean target-list
+.PHONY: default clean target-list distclean
TARGET=default
include ./base.mk
rm -f ./config.mk
@echo " "
+distclean:
+ rm -f lib/user/*.so* lib/user/*.a
+ rm -f lib/kernel/*.ko
return r;
}
-static void *segdev_map(const char *name, uint64_t size)
+static void *segdev_map(const char *name, uint64_t size, struct xseg *seg)
{
struct xseg *xseg = NULL;
/* map() holds a reference to the segment */
struct segdev *dev = segdev_get(0);
+ struct segpriv *priv;
int r;
r = IS_ERR(dev) ? PTR_ERR(dev) : 0;
if (r)
if (size > dev->segsize)
goto out;
+ priv = dev->priv;
+ if (priv->segno >= nr_xsegments)
+ goto out;
+
+ if (seg)
+ xsegments[priv->segno] = seg;
+
xseg = (void *)dev->segment;
out:
return xseg;
static void segdev_unmap(void *ptr, uint64_t size)
{
struct segdev *segdev = segdev_get(0);
+ struct segpriv *priv;
int r = IS_ERR(segdev) ? PTR_ERR(segdev) : 0;
if (r)
return;
+ priv = segdev->priv;
+ if (priv->segno >= nr_xsegments)
+ goto out;
+
+ xsegments[priv->segno] = NULL;
+
+out:
/* unmap() releases the reference taken by map() */
segdev_put(segdev);
+
+ segdev_put(segdev);
}
static void segdev_callback(struct segdev *dev)
struct segpriv *priv = dev->priv;
struct xseg_private *xpriv;
uint32_t portno;
- if (priv->segno > nr_xsegments)
+ if (priv->segno >= nr_xsegments)
return;
if (dev->buffer_index != sizeof(uint32_t)) {
return;
}
- portno = *(uint32_t *)dev->buffer;
xseg = xsegments[priv->segno];
xpriv = xseg->priv;
- if (xpriv->wakeup)
+ if (xpriv->wakeup) {
+ portno = *(uint32_t *)dev->buffer;
xpriv->wakeup(xseg, portno);
+ }
}
static struct xseg_type xseg_segdev = {
segdev->priv = segpriv;
r = 0;
out:
+ segdev_put(segdev);
return r;
}
xsegments[0] = NULL;
if (!r)
segdev->callback = NULL;
+
+ segdev_put(segdev);
return;
}
return shm_unlink(name);
}
-static void *posix_map(const char *name, uint64_t size)
+static void *posix_map(const char *name, uint64_t size, struct xseg *seg)
{
struct xseg *xseg;
int fd;
+
+ if (seg)
+ XSEGLOG("struct xseg * is not NULL. Ignoring...\n");
+
fd = shm_open(name, O_RDWR, 0000);
if (fd < 0) {
XSEGLOG("Failed to open '%s' for mapping: %s\n",
return 0;
}
-static void *segdev_map(const char *name, uint64_t size)
+static void *segdev_map(const char *name, uint64_t size, struct xseg *seg)
{
struct xseg *xseg;
int fd;
+
+ if (seg)
+ XSEGLOG("struct xseg * not NULL. Ignoring...\n");
+
fd = opendev();
if (fd < 0)
return NULL;
static int segdev_signal(struct xseg *xseg, uint32_t portno)
{
- struct xseg_port *port = &xseg->ports[portno];
- return write(opendev(), &port, sizeof(port));
+ return write(opendev(), &portno, sizeof(portno));
}
static void *segdev_malloc(uint64_t size)
int err;
for (;;) {
- xreq = xseg_receive(xseg, xsegbd_dev->src_portno);
+ xreq = xseg_receive(xseg, portno);
if (!xreq)
break;
default: all
-all: blockd filed vlmcd xseg
+all: blockd filed xseg
filed: filed.c $(BASE)/xseg/xseg.h
$(CC) $(CFLAGS) -o $@ $< $(INC) -L$(LIB) -lxseg -lpthread
{
if (!xseg && cmd_join())
return -1;
+ xseg_leave(xseg);
xseg_destroy(xseg);
xseg = NULL;
fprintf(stderr, "Segment destroyed.\n");
goto out_unlock;
clear_bit(SEGDEV_READY, &dev->flags);
- ret = wait_event_interruptible(dev->wq, atomic_read(&dev->usercount) < 1);
+ ret = wait_event_interruptible(dev->wq, atomic_read(&dev->usercount) <= 1);
if (ret)
goto out_unlock;
clean:
make -C xq clean
rm -f _initialize.c _initialize.o
- rm -f xseg.o xseg.pic.o
- rm -f libxseg.a
+ rm -f xseg.o xseg.pic.o xseg_user.o
+ rm -f libxseg.a libxseg.map
rm -f libxseg.so libxseg.so.$(MAJOR) libxseg.so.$(MAJOR).$(MINOR)
-
load_module "segdev"
load_module "xseg_segdev"
mk_chardev
+ "${XSEG_HOME}/peers/user/xseg" "${SPEC}" create
load_module "xsegbd" "spec=$SPEC"
}
# @param $1 target/volume name
# @param $2 xseg port
function spawn_blockd {
- "${XSEG_HOME}peers/blockd" "$1" -p "$2" -g "$SPEC" -n ${NR_OPS} &> "${BLOCKD_LOGS}/$1" || fail "blockd"
+ "${XSEG_HOME}peers/user/blockd" "$1" -p "$2" -g "$SPEC" -n ${NR_OPS} &> "${BLOCKD_LOGS}/$1" || fail "blockd"
}
function spawn_filed {
- "${XSEG_HOME}peers/filed" "$1" -p "$2" -g "${SPEC}" -n ${NR_OPS} &> "${BLOCKD_LOGS}/filed-${HOSTNAME}" &
+ "${XSEG_HOME}peers/user/filed" "$1" -p "$2" -g "${SPEC}" -n ${NR_OPS} &> "${BLOCKD_LOGS}/filed-${HOSTNAME}" &
}
# map_volume - Map a volume to an xsegbd device
old_dir = os.getcwd()
os.chdir(IMAGES)
f = os.open(BLOCKD_LOGS + name, os.O_CREAT | os.O_WRONLY)
- r = subprocess.Popen([XSEG_HOME + "peers/blockd", name, "-p", str(port),
+ r = subprocess.Popen([XSEG_HOME + "peers/user/blockd", name, "-p", str(port),
"-g", SPEC, "-n", str(NR_OPS)], stdout=f, stderr=f)
os.chdir(IMAGES)
BLOCKD_LOGS="/root/archip_logs/"
FILED_PORT=0
NR_OPS=16
+REQS=512
def vlmc_list(args):
print "name\t\t\t\tsize"
goto out_err;
}
- xseg = xops->map(cfg->name, size);
+ xseg = xops->map(cfg->name, size, NULL);
if (!xseg) {
XSEGLOG("cannot map segment!\n");
goto out_deallocate;
void xseg_destroy(struct xseg *xseg)
{
- struct xseg_type *type = __find_or_load_type(xseg->config.type);
+ struct xseg_type *type;
+
+ __lock_domain();
+ type = __find_or_load_type(xseg->config.type);
if (!type) {
XSEGLOG("no segment type '%s'\n", xseg->config.type);
- return;
+ goto out;
}
/* should destroy() leave() first? */
type->ops.deallocate(xseg->config.name);
+out:
+ __unlock_domain();
}
static int pointer_ok( unsigned long ptr,
goto err_seg;
}
- __xseg = xops->map(segname, XSEG_MIN_PAGE_SIZE);
+ __xseg = xops->map(segname, XSEG_MIN_PAGE_SIZE, NULL);
if (!__xseg) {
XSEGLOG("Cannot map segment");
goto err_priv;
/* XSEGLOG("joined segment of size: %lu\n", (unsigned long)size); */
xops->unmap(__xseg, XSEG_MIN_PAGE_SIZE);
- __xseg = xops->map(segname, size);
+ __xseg = xops->map(segname, size, xseg);
if (!__xseg) {
XSEGLOG("Cannot map segment");
goto err_priv;
priv->segment_type = *segtype;
priv->peer_type = *peertype;
priv->wakeup = wakeup;
+ xseg->max_peer_types = __xseg->max_peer_types;
priv->peer_types = pops->malloc(sizeof(void *) * xseg->max_peer_types);
if (!priv->peer_types) {
}
memset(priv->peer_types, 0, sizeof(void *) * xseg->max_peer_types);
+ xseg->priv = priv;
xseg->config = __xseg->config;
xseg->version = __xseg->version;
xseg->requests = XSEG_TAKE_PTR(__xseg->requests, __xseg);
return NULL;
}
-/* void xseg_leave(struct xseg *xseg) { at least free allocated memory } */
+void xseg_leave(struct xseg *xseg)
+{
+ struct xseg_type *type;
+
+ __lock_domain();
+ type = __find_or_load_type(xseg->config.type);
+ if (!type) {
+ XSEGLOG("no segment type '%s'\n", xseg->config.type);
+ __unlock_domain();
+ return;
+ }
+ __unlock_domain();
+
+ type->ops.unmap(xseg->segment, xseg->segment_size);
+}
int xseg_prepare_wait(struct xseg *xseg, uint32_t portno)
{
void (*mfree)(void *mem);
long (*allocate)(const char *name, uint64_t size);
long (*deallocate)(const char *name);
- void *(*map)(const char *name, uint64_t size);
+ void *(*map)(const char *name, uint64_t size, struct xseg *seg);
void (*unmap)(void *xseg, uint64_t size);
};
EXPORT_SYMBOL(xseg_create);
EXPORT_SYMBOL(xseg_destroy);
EXPORT_SYMBOL(xseg_join);
+EXPORT_SYMBOL(xseg_leave);
EXPORT_SYMBOL(xseg_bind_port);
EXPORT_SYMBOL(xseg_alloc_requests);
EXPORT_SYMBOL(xseg_free_requests);