コード例 #1
0
static int rados_metatile_expire(struct storage_backend * store, const char *xmlconfig, int x, int y, int z) {

    struct stat_info tile_stat;
    struct rados_ctx * ctx = (struct rados_ctx *)store->storage_ctx;
    char meta_path[PATH_MAX];
    char tmp[PATH_MAX];
    int err;

    //TODO: deal with options
    const char *options = "";
    rados_xyzo_to_storagekey(xmlconfig, options, x, y, z, meta_path);
    err = rados_read(ctx->io, meta_path, (char *)&tile_stat, sizeof(struct stat_info), 0);

    if (err < 0) {
        if (-err == ENOENT) {
            log_message(STORE_LOGLVL_DEBUG, "Tile %s does not exist, can't expire", rados_tile_storage_id(store, xmlconfig, options, x, y, z, tmp));
            return -1;
        } else {
            log_message(STORE_LOGLVL_ERR, "Failed to read tile metadata for %s: %s", rados_tile_storage_id(store, xmlconfig, options, x, y, z, tmp), strerror(-err));
        }
        return -2;
    }

    tile_stat.expired = 1;

    err = rados_write(ctx->io, meta_path, (char *)&tile_stat, sizeof(struct stat_info), 0);

    if (err < 0) {
        log_message(STORE_LOGLVL_ERR, "failed to write expiry data for %s: %s", rados_tile_storage_id(store, xmlconfig, options, x, y, z, tmp), strerror(-err));
        return -3;
    }

    return 0;
}
コード例 #2
0
ファイル: rados.c プロジェクト: CommerceRack/uwsgi
static int uwsgi_rados_read_sync(struct wsgi_request *wsgi_req, rados_ioctx_t *ctx, const char *key, size_t remains) {
	uint64_t off = 0;
	while(remains > 0) {
		char buf[8192];
		int rlen = rados_read(ctx, key, buf, UMIN(remains, 8192), off);
		if (rlen <= 0) return -1;
		if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) return -1;
		remains -= rlen;
		off += rlen;
	}
	return 0;
}
コード例 #3
0
ファイル: rados.c プロジェクト: Nikolo/uwsgi
static int uwsgi_rados_read_sync(struct wsgi_request *wsgi_req, rados_ioctx_t ctx, const char *key, uint64_t off, uint64_t remains, size_t bufsize) {
	char* buf = uwsgi_malloc(UMIN(remains, bufsize));
	while(remains > 0) {
		int rlen = rados_read(ctx, key, buf, UMIN(remains, bufsize), off);
		if (rlen <= 0) goto end;
		if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) goto end;
		remains -= rlen;
		off += rlen;
	}
        free(buf);
	return 0;
end:
        free(buf);
        return -1;
}
コード例 #4
0
static char * read_meta_data(struct storage_backend * store, const char *xmlconfig, const char *options, int x, int y, int z) {
    int mask;
    int err;
    char meta_path[PATH_MAX];
    struct rados_ctx * ctx = (struct rados_ctx *)store->storage_ctx;
    unsigned int header_len = sizeof(struct stat_info) + sizeof(struct meta_layout) + METATILE*METATILE*sizeof(struct entry);

    mask = METATILE - 1;
    x &= ~mask;
    y &= ~mask;

    if ((ctx->metadata_cache.x == x) && (ctx->metadata_cache.y == y) && (ctx->metadata_cache.z == z) && (strcmp(ctx->metadata_cache.xmlname, xmlconfig) == 0)) {
        //log_message(STORE_LOGLVL_DEBUG, "Returning cached data for %s %i %i %i", ctx->metadata_cache.xmlname, ctx->metadata_cache.x, ctx->metadata_cache.y, ctx->metadata_cache.z);
        return ctx->metadata_cache.data;
    } else {
        //log_message(STORE_LOGLVL_DEBUG, "Retrieving fresh metadata");
        rados_xyzo_to_storagekey(xmlconfig, options, x, y, z, meta_path);
        err = rados_read(ctx->io, meta_path, ctx->metadata_cache.data, header_len, 0);

        if (err < 0) {
            if (-err == ENOENT) {
                log_message(STORE_LOGLVL_DEBUG, "cannot read data from rados pool %s: %s\n", ctx->pool, strerror(-err));
            } else {
                log_message(STORE_LOGLVL_ERR, "cannot read data from rados pool %s: %s\n", ctx->pool, strerror(-err));
            }
            ctx->metadata_cache.x = -1;
            ctx->metadata_cache.y = -1;
            ctx->metadata_cache.z = -1;
            return NULL;
        }
        ctx->metadata_cache.x = x;
        ctx->metadata_cache.y = y;
        ctx->metadata_cache.z = z;
        strncpy(ctx->metadata_cache.xmlname, xmlconfig, XMLCONFIG_MAX - 1);
        return ctx->metadata_cache.data;
    }
}
コード例 #5
0
ファイル: io_context.c プロジェクト: johnl/rados.rb
static VALUE nogvl_ioctx_read(void *ptr) {
  struct nogvl_iop_args *args = ptr;
	return (VALUE)rados_read(*args->ioctx, args->oid, args->buf, args->len, args->offset);
}
コード例 #6
0
ファイル: testrados.c プロジェクト: ShintaroNakai/ceph
static int testrados(void)
{
	char tmp[32];
	int i, r;
	rados_t cl;

	if (rados_create(&cl, NULL) < 0) {
		printf("error initializing\n");
		return 1;
	}

	if (rados_conf_read_file(cl, NULL)) {
		printf("error reading configuration file\n");
		return 1;
	}

	// Try to set a configuration option that doesn't exist.
	// This should fail.
	if (!rados_conf_set(cl, "config option that doesn't exist",
			"some random value")) {
		printf("error: succeeded in setting nonexistent config option\n");
		return 1;
	}

	if (rados_conf_get(cl, "log to stderr", tmp, sizeof(tmp))) {
		printf("error: failed to read log_to_stderr from config\n");
		return 1;
	}

	// Can we change it?
	if (rados_conf_set(cl, "log to stderr", "2")) {
		printf("error: error setting log_to_stderr\n");
		return 1;
	}
	if (rados_conf_get(cl, "log to stderr", tmp, sizeof(tmp))) {
		printf("error: failed to read log_to_stderr from config\n");
		return 1;
	}
	if (tmp[0] != '2') {
		printf("error: new setting for log_to_stderr failed to take effect.\n");
		return 1;
	}

	if (rados_connect(cl)) {
		printf("error connecting\n");
		return 1;
	}
	if (rados_connect(cl) == 0) {
		printf("second connect attempt didn't return an error\n");
		return 1;
	}

	/* create an io_ctx */
	r = rados_pool_create(cl, "foo");
	printf("rados_pool_create = %d\n", r);

	rados_ioctx_t io_ctx;
	r = rados_ioctx_create(cl, "foo", &io_ctx);
	printf("rados_ioctx_create = %d, io_ctx = %p\n", r, io_ctx);

	/* list all pools */
	{
		int buf_sz = rados_pool_list(cl, NULL, 0);
		printf("need buffer size of %d\n", buf_sz);
		char buf[buf_sz];
		int r = rados_pool_list(cl, buf, buf_sz);
		if (r != buf_sz) {
			printf("buffer size mismatch: got %d the first time, but %d "
			"the second.\n", buf_sz, r);
			return 1;
		}
		const char *b = buf;
		printf("begin pools.\n");
		while (1) {
		if (b[0] == '\0')
		break;
		printf(" pool: '%s'\n", b);
		b += strlen(b) + 1;
		};
		printf("end pools.\n");
	}


	/* stat */
	struct rados_pool_stat_t st;
	r = rados_ioctx_pool_stat(io_ctx, &st);
	printf("rados_ioctx_pool_stat = %d, %lld KB, %lld objects\n", r, (long long)st.num_kb, (long long)st.num_objects);

	/* snapshots */
	r = rados_ioctx_snap_create(io_ctx, "snap1");
	printf("rados_ioctx_snap_create snap1 = %d\n", r);
	rados_snap_t snaps[10];
	r = rados_ioctx_snap_list(io_ctx, snaps, 10);
	for (i=0; i<r; i++) {
		char name[100];
		rados_ioctx_snap_get_name(io_ctx, snaps[i], name, sizeof(name));
		printf("rados_ioctx_snap_list got snap %lld %s\n", (long long)snaps[i], name);
	}
	rados_snap_t snapid;
	r = rados_ioctx_snap_lookup(io_ctx, "snap1", &snapid);
	printf("rados_ioctx_snap_lookup snap1 got %lld, result %d\n", (long long)snapid, r);
	r = rados_ioctx_snap_remove(io_ctx, "snap1");
	printf("rados_ioctx_snap_remove snap1 = %d\n", r);

	/* sync io */
	time_t tm;
	char buf[128], buf2[128];
	time(&tm);
	snprintf(buf, 128, "%s", ctime(&tm));
	const char *oid = "foo_object";
	r = rados_write(io_ctx, oid, buf, strlen(buf) + 1, 0);
	printf("rados_write = %d\n", r);
	r = rados_read(io_ctx, oid, buf2, sizeof(buf2), 0);
	printf("rados_read = %d\n", r);
	if (memcmp(buf, buf2, r))
		printf("*** content mismatch ***\n");

	/* attrs */
	if (do_rados_setxattr(io_ctx, oid, "b", "2"))
		return 1;
	if (do_rados_setxattr(io_ctx, oid, "a", "1"))
		return 1;
	if (do_rados_setxattr(io_ctx, oid, "c", "3"))
		return 1;
	if (do_rados_getxattr(io_ctx, oid, "a", "1"))
		return 1;
	if (do_rados_getxattr(io_ctx, oid, "b", "2"))
		return 1;
	if (do_rados_getxattr(io_ctx, oid, "c", "3"))
		return 1;
	const char *exkeys[] = { "a", "b", "c", NULL };
	const char *exvals[] = { "1", "2", "3", NULL };
	if (do_rados_getxattrs(io_ctx, oid, exkeys, exvals))
		return 1;

	uint64_t size;
	time_t mtime;
	r = rados_stat(io_ctx, oid, &size, &mtime);
	printf("rados_stat size = %lld mtime = %d = %d\n", (long long)size, (int)mtime, r);
	r = rados_stat(io_ctx, "does_not_exist", NULL, NULL);
	printf("rados_stat(does_not_exist) = %d\n", r);

	/* exec */
	rados_exec(io_ctx, oid, "crypto", "md5", buf, strlen(buf) + 1, buf, 128);
	printf("exec result=%s\n", buf);
	r = rados_read(io_ctx, oid, buf2, 128, 0);
	printf("read result=%s\n", buf2);
	printf("size=%d\n", r);

	/* aio */
	rados_completion_t a, b;
	rados_aio_create_completion(0, 0, 0, &a);
	rados_aio_create_completion(0, 0, 0, &b);
	rados_aio_write(io_ctx, "a", a, buf, 100, 0);
	rados_aio_write(io_ctx, "../b/bb_bb_bb\\foo\\bar", b, buf, 100, 0);
	rados_aio_wait_for_safe(a);
	printf("a safe\n");
	rados_aio_wait_for_safe(b);
	printf("b safe\n");
	rados_aio_release(a);
	rados_aio_release(b);

	/* test flush */
	printf("testing aio flush\n");
	rados_completion_t c;
	rados_aio_create_completion(0, 0, 0, &c);
	rados_aio_write(io_ctx, "c", c, buf, 100, 0);
	int safe = rados_aio_is_safe(c);
	printf("a should not yet be safe and ... %s\n", safe ? "is":"is not");
	assert(!safe);
	rados_aio_flush(io_ctx);
	safe = rados_aio_is_safe(c);
	printf("a should be safe and ... %s\n", safe ? "is":"is not");
	assert(safe);
	rados_aio_release(c);
	
	rados_read(io_ctx, "../b/bb_bb_bb\\foo\\bar", buf2, 128, 0);

	/* list objects */
	rados_list_ctx_t h;
	r = rados_objects_list_open(io_ctx, &h);
	printf("rados_list_objects_open = %d, h = %p\n", r, h);
	const char *poolname;
	while (rados_objects_list_next(h, &poolname) == 0)
		printf("rados_list_objects_next got object '%s'\n", poolname);
	rados_objects_list_close(h);

	/* stat */
	r = rados_ioctx_pool_stat(io_ctx, &st);
	printf("rados_stat_pool = %d, %lld KB, %lld objects\n", r, (long long)st.num_kb, (long long)st.num_objects);

	/* delete a pool */
	printf("rados_delete_pool = %d\n", r);
	rados_ioctx_destroy(io_ctx);

	r = rados_pool_delete(cl, "foo");
	printf("rados_ioctx_pool_delete = %d\n", r);

	rados_shutdown(cl);
	return 0;
}
コード例 #7
0
ファイル: rados-fd.c プロジェクト: karcaw/bareos-contrib
/*
 * Bareos is calling us to do the actual I/O
 */
static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
{
   int io_count;
   plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext;

   if (!p_ctx) {
      return bRC_Error;
   }

   switch(io->func) {
   case IO_OPEN:
      p_ctx->offset = 0;
      io->status = 0;
      io->io_errno = 0;
      break;
   case IO_READ:
      io_count = rados_read(p_ctx->ioctx, p_ctx->object_name, io->buf, io->count, p_ctx->offset);
      if (io_count >= 0) {
         p_ctx->offset += io_count;
         io->status = io_count;
         io->io_errno = 0;
      } else {
         io->io_errno = -io_count;
         goto bail_out;
      }
      break;
   case IO_WRITE:
      io_count = rados_write(p_ctx->ioctx, p_ctx->object_name, io->buf, io->count, p_ctx->offset);
#if LIBRADOS_VERSION_CODE <= 17408
      if (io_count >= 0) {
         p_ctx->offset += io_count;
         io->status = io_count;
#else
      if (io_count == 0) {
         p_ctx->offset += io->count;
         io->status = io->count;
#endif
         io->io_errno = 0;
      } else {
         io->io_errno = -io_count;
         goto bail_out;
      }
      break;
   case IO_CLOSE:
      p_ctx->offset = 0;
      io->status = 0;
      io->io_errno = 0;
      break;
   case IO_SEEK:
      Jmsg(ctx, M_ERROR, "Illegal Seek request on rados device.");
      Dmsg(ctx, dbglvl, "Illegal Seek request on rados device.");
      io->io_errno = EINVAL;
      goto bail_out;
   }

   return bRC_OK;

bail_out:
   io->lerror = 0;
   io->win32 = false;
   io->status = -1;

   return bRC_Error;
}

/*
 * See if we need to do any postprocessing after the restore.
 */
static bRC end_restore_job(bpContext *ctx, void *value)
{
   bRC retval = bRC_OK;
   plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext;

   if (!p_ctx) {
      return bRC_Error;
   }

   Dmsg(ctx, dbglvl, "rados-fd: entering end_restore_job\n");

   Dmsg(ctx, dbglvl, "rados-fd: leaving end_restore_job\n");

   return retval;
}
コード例 #8
0
static int rados_tile_read(struct storage_backend * store, const char *xmlconfig, const char *options, int x, int y, int z, char *buf, size_t sz, int * compressed, char * log_msg) {

    char meta_path[PATH_MAX];
    int meta_offset;
    unsigned int header_len = sizeof(struct meta_layout) + METATILE*METATILE*sizeof(struct entry);
    struct meta_layout *m = (struct meta_layout *)malloc(header_len);
    size_t file_offset, tile_size;
    int mask;
    int err;
    char * buf_raw;

    mask = METATILE - 1;
    meta_offset = (x & mask) * METATILE + (y & mask);

    rados_xyzo_to_storagekey(xmlconfig, options, x, y, z, meta_path);

    buf_raw = read_meta_data(store, xmlconfig, options, x, y, z);
    if (buf_raw == NULL) {
        snprintf(log_msg,1024, "Failed to read metadata of tile\n");
        free(m);
        return -3;
    }

    memcpy(m, buf_raw + sizeof(struct stat_info), header_len);

    if (memcmp(m->magic, META_MAGIC, strlen(META_MAGIC))) {
        if (memcmp(m->magic, META_MAGIC_COMPRESSED, strlen(META_MAGIC_COMPRESSED))) {
            snprintf(log_msg,1024, "Meta file header magic mismatch\n");
            free(m);
            return -4;
        } else {
            *compressed = 1;
        }
    } else *compressed = 0;

    // Currently this code only works with fixed metatile sizes (due to xyz_to_meta above)
    if (m->count != (METATILE * METATILE)) {
        snprintf(log_msg, 1024, "Meta file header bad count %d != %d\n", m->count, METATILE * METATILE);
        free(m);
        return -5;
    }

    file_offset = m->index[meta_offset].offset + sizeof(struct stat_info);
    tile_size   = m->index[meta_offset].size;

    free(m);

    if (tile_size > sz) {
        snprintf(log_msg, 1024, "Truncating tile %zd to fit buffer of %zd\n", tile_size, sz);
        tile_size = sz;
        return -6;
    }

    err = rados_read(((struct rados_ctx *)store->storage_ctx)->io, meta_path, buf, tile_size, file_offset);

    if (err < 0) {
        snprintf(log_msg, 1024, "Failed to read tile data from rados %s offset: %li length: %li: %s\n", meta_path, file_offset, tile_size, strerror(-err));
        return -1;
    }

    return tile_size;
}