lkml.org 
[lkml]   [2009]   [Jun]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] open-osd: osdblk User Mode utility

    A minimal user-mode application to Create / Remove / Resize
    OSD objects from a device, for use with the osdblk.ko block
    device driver.

    See inside patch for Usage instructions.

    Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
    ---
    usr/Makefile | 12 ++-
    usr/osdblk.c | 336 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    2 files changed, 347 insertions(+), 1 deletions(-)
    create mode 100644 usr/osdblk.c

    diff --git a/usr/Makefile b/usr/Makefile
    index 2021d9b..534fba7 100755
    --- a/usr/Makefile
    +++ b/usr/Makefile
    @@ -36,7 +36,7 @@ CFLAGS = -fPIC $(CWARN) $(INCLUDES) $(DEFINES)

    OSD_LIBS=-L../lib -losd

    -ALL = osd_test mkfs.exofs
    +ALL = osd_test mkfs.exofs osdblk
    all: $(DEPEND) $(ALL)

    clean: $(ALL:=_clean)
    @@ -78,6 +78,16 @@ mkfs.exofs_clean:

    $(DEPEND): $(mkfs_COMMON_OBJ:.o=.c) $(mkfs_OBJ:.o=.c)

    +# =============== osdblk ======================================================
    +osdblk_OBJ=osdblk.o
    +
    +osdblk: $(osdblk_OBJ)
    + $(CC) -o $@ $^ $(OSD_LIBS)
    +
    +osdblk_clean:
    +
    +$(DEPEND): $(osdblk_OBJ:.o=.c)
    +
    # =============== common rules =================================================
    # every thing should compile if Makefile changed
    %.o: %.c Makefile
    diff --git a/usr/osdblk.c b/usr/osdblk.c
    new file mode 100644
    index 0000000..f7df257
    --- /dev/null
    +++ b/usr/osdblk.c
    @@ -0,0 +1,336 @@
    +/*
    + * osdblk.c - A user-mode program that calls into the osd ULD
    + *
    + * Copyright (C) 2009 Panasas Inc. All rights reserved.
    + *
    + * Authors:
    + * Boaz Harrosh <bharrosh@panasas.com>
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + *
    + * 1. Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + * notice, this list of conditions and the following disclaimer in the
    + * documentation and/or other materials provided with the distribution.
    + * 3. Neither the name of the Panasas company nor the names of its
    + * contributors may be used to endorse or promote products derived
    + * from this software without specific prior written permission.
    + *
    + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
    + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + */
    +
    +#include <open-osd/libosd.h>
    +
    +#include <getopt.h>
    +#include <stdio.h>
    +#include <stdlib.h>
    +
    +#define OSDBLK_ERR(fmt, a...) fprintf(stderr, "osdblk: " fmt, ##a)
    +#define OSDBLK_INFO(fmt, a...) printf("osdblk: " fmt, ##a)
    +
    +#ifdef CONFIG_OSDBLK_DEBUG
    +#define OSDBLK_DBGMSG(fmt, a...) \
    + printf("osdblk @%s:%d: " fmt, __func__, __LINE__, ##a)
    +#else
    +#define EXOFS_DBGMSG(fmt, a...) \
    + if (0) printf(fmt, ##a);
    +#endif
    +
    +static void usage(void)
    +{
    + static char msg[] = {
    + "usage: osdblk COMMAND --pid=pid_no --obj=obj_no --length=ob_size /dev/osdX\n"
    + "\n"
    + "COMMAND is one of: --create | --remove | --resize\n"
    + "--create | -c\n"
    + " Create a new object. If object exist returns error\n"
    + " --length can be used to denote an initial size\n"
    + "\n"
    + "--remove\n"
    + " remove an existing object. If does not exist does nothing\n"
    + " --length is ignored\n"
    + "\n"
    + "--resize | -s\n"
    + " Resize an existing object. If does not exist errors\n"
    + " If --length=0 then does nothing (Only check for existance)\n"
    + "\n"
    + "--pid=pid_no | -p pid_no\n"
    + " pid_no is the partition 64bit number of the object in question\n"
    + " Both 0xabc hex or decimal anotation can be used\n"
    + "\n"
    + "--obj=obj_no | -o obj_no\n"
    + " obj_no is the object 64bit number of the object in question\n"
    + " Both 0xabc hex or decimal anotation can be used\n"
    + "\n"
    + "--length=size | -l size\n"
    + " \"size\" is the new size of the object to be set\n"
    + " 0xhex or decimal can be used. G, M, K can be appended to the\n"
    + " number to denote base-two Giga Mega or Kilo\n"
    + "\n"
    + "/dev/osdX is the osd LUN (char-dev) to use containing the object\n"
    + "\n"
    + "Description: Create Remove or Resize an OSD object on an OSD LUN\n"
    + " The object can later be used, for example, by the\n"
    + " osdblk device driver\n"
    + };
    +
    + printf(msg);
    +}
    +
    +#define _LLU(x) ((unsigned long long)x)
    +
    +static u64 ullwithGMK(char *optarg)
    +{
    + char *pGMK;
    + u64 mul;
    + u64 val = strtoll(optarg, &pGMK, 0);
    +
    + switch (*pGMK) {
    + case 'K':
    + case 'k':
    + mul = 1024LLU;
    + break;
    + case 'M':
    + mul = 1024LLU * 1024LLU;
    + break;
    + case 'G':
    + mul = 1024LLU * 1024LLU * 1024LLU;
    + break;
    + default:
    + mul = 1;
    + }
    +
    + return val * mul;
    +}
    +
    +static void osdblk_make_credential(u8 *creds, struct osd_obj_id *obj,
    + bool is_v1)
    +{
    + osd_sec_init_nosec_doall_caps(creds, obj, false, is_v1);
    +}
    +
    +static int osdblk_exec(struct osd_request *or, u8 *cred)
    +{
    + struct osd_sense_info osi;
    + int ret;
    +
    + ret = osd_finalize_request(or, 0, cred, NULL);
    + if (ret) {
    + OSDBLK_ERR("Error: Faild to osd_finalize_request() => %d\n",
    + ret);
    + return ret;
    + }
    +
    + osd_execute_request(or);
    + ret = osd_req_decode_sense(or, &osi);
    +
    + if (ret) { /* translate to Linux codes */
    + if (osi.additional_code == scsi_invalid_field_in_cdb) {
    + if (osi.cdb_field_offset == OSD_CFO_STARTING_BYTE)
    + ret = 0; /*this is OK*/
    + if (osi.cdb_field_offset == OSD_CFO_OBJECT_ID)
    + ret = -ENOENT;
    + else
    + ret = -EINVAL;
    + } else if (osi.additional_code == osd_quota_error)
    + ret = -ENOSPC;
    + else
    + ret = -EIO;
    + }
    +
    + return ret;
    +}
    +
    +static int do_resize(struct osd_dev *od, struct osd_obj_id *obj, u64 size)
    +{
    + struct osd_request *or = osd_start_request(od, GFP_KERNEL);
    + __be64 be_size = cpu_to_be64(size);
    + u8 creds[OSD_CAP_LEN];
    + struct osd_attr attr_logical_length = ATTR_SET(
    + OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH,
    + sizeof(be_size), &be_size);
    + int ret;
    +
    + if (unlikely(!or))
    + return -ENOMEM;
    +
    + osdblk_make_credential(creds, obj, osd_req_is_ver1(or));
    +
    + osd_req_set_attributes(or, obj);
    + osd_req_add_set_attr_list(or, &attr_logical_length, 1);
    +
    + ret = osdblk_exec(or, creds);
    + osd_end_request(or);
    +
    + if (ret)
    + return ret;
    +
    + OSDBLK_INFO("Resized: pid=0x%llx oid=0x%llx length=0x%llx\n",
    + _LLU(obj->partition), _LLU(obj->id),
    + _LLU(size));
    +
    + return 0;
    +}
    +
    +static int do_create(struct osd_dev *od, struct osd_obj_id *obj, u64 size)
    +{
    + struct osd_request *or = osd_start_request(od, GFP_KERNEL);
    + u8 creds[OSD_CAP_LEN];
    + int ret;
    +
    + if (unlikely(!or))
    + return -ENOMEM;
    +
    + osdblk_make_credential(creds, obj, osd_req_is_ver1(or));
    + osd_req_create_object(or, obj);
    + ret = osdblk_exec(or, creds);
    + osd_end_request(or);
    +
    + if (ret)
    + return ret;
    +
    + OSDBLK_INFO("Created: pid=0x%llx oid=0x%llx\n",
    + _LLU(obj->partition), _LLU(obj->id));
    +
    + return do_resize(od, obj, size);
    +}
    +
    +static int do_remove(struct osd_dev *od, struct osd_obj_id *obj)
    +{
    + struct osd_request *or = osd_start_request(od, GFP_KERNEL);
    + u8 creds[OSD_CAP_LEN];
    + int ret;
    +
    + if (unlikely(!or))
    + return -ENOMEM;
    +
    + osdblk_make_credential(creds, obj, osd_req_is_ver1(or));
    + osd_req_remove_object(or, obj);
    + ret = osdblk_exec(or, creds);
    + osd_end_request(or);
    +
    + if (ret)
    + return ret;
    +
    + OSDBLK_INFO("Removed: pid=0x%llx oid=0x%llx\n",
    + _LLU(obj->partition), _LLU(obj->id));
    +
    + return 0;
    +}
    +
    +enum osd_todo {
    + osd_none = 0,
    + osd_create,
    + osd_remove,
    + osd_resize,
    +};
    +
    +static int _do(char *path, struct osd_obj_id *obj, u64 size,
    + enum osd_todo todo)
    +{
    + struct osd_dev *od;
    + int ret;
    +
    + ret = osd_open(path, &od);
    + if (ret)
    + return ret;
    +
    + switch (todo) {
    + case osd_create:
    + ret = do_create(od, obj, size);
    + break;
    + case osd_remove:
    + ret = do_remove(od, obj);
    + break;
    + case osd_resize:
    + ret = do_resize(od, obj, size);
    + break;
    + default:
    + usage();
    + return 1;
    + }
    +
    + osd_close(od);
    +
    + /* osd lib has Kernel API which return negative errors */
    + return -ret;
    +}
    +
    +int main(int argc, char *argv[])
    +{
    + struct option opt[] = {
    + {.name = "create", .has_arg = 0, .flag = NULL, .val = 'c'} ,
    + {.name = "remove", .has_arg = 0, .flag = NULL, .val = 'r'} ,
    + {.name = "resize", .has_arg = 0, .flag = NULL, .val = 's'} ,
    + {.name = "pid", .has_arg = 1, .flag = NULL, .val = 'p'} ,
    + {.name = "oid", .has_arg = 1, .flag = NULL, .val = 'o'} ,
    + {.name = "size", .has_arg = 1, .flag = NULL, .val = 'l'} ,
    +
    + {.name = 0, .has_arg = 0, .flag = 0, .val = 0} ,
    + };
    + struct osd_obj_id obj = {.id = 0};
    + enum osd_todo todo = osd_none;
    + u64 size = 0;
    + char op;
    + int err;
    +
    + while ((op = getopt_long(argc, argv, "csp:o:l:", opt, NULL)) != -1) {
    + switch (op) {
    + case 'c':
    + todo = osd_create;
    + break;
    + case 'r':
    + todo = osd_remove;
    + break;
    + case 's':
    + todo = osd_resize;
    + break;
    +
    + case 'p':
    + obj.partition = strtoll(optarg, NULL, 0);
    + break;
    + case 'o':
    + obj.id = strtoll(optarg, NULL, 0);
    + break;
    +
    + case 'l':
    + size = ullwithGMK(optarg);
    + break;
    + }
    + }
    +
    + argc -= optind;
    + argv += optind;
    +
    + if (argc <= 0) {
    + usage();
    + return 1;
    + }
    +
    + if ((todo == osd_none) || !obj.partition || !obj.id) {
    + usage();
    + return 1;
    + }
    +
    + err = _do(argv[0], &obj, size, todo);
    + if (err)
    + OSDBLK_ERR("Error: %s\n", strerror(err));
    +
    + return err;
    +}
    --
    1.6.2.1



    \
     
     \ /
      Last update: 2009-06-18 14:59    [W:0.038 / U:122.952 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site