X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Fobdctl.c;h=25666c3d348f0b17829a158b4b15fe9c79026ae4;hb=befd9c343fc9ba20a7b26f6dabce0a5521b3b1e3;hp=66bb5c0775e13bc50528d2c1fae3b6c93899bc2f;hpb=c5665694dc019721c48140d2c5f842fc62420444;p=fs%2Flustre-release.git diff --git a/lustre/utils/obdctl.c b/lustre/utils/obdctl.c index 66bb5c0..25666c3 100644 --- a/lustre/utils/obdctl.c +++ b/lustre/utils/obdctl.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #define printk printf @@ -49,6 +50,8 @@ #include #include +#include /* needed for PAGE_SIZE - rread*/ + #define __KERNEL__ #include #undef __KERNEL__ @@ -62,7 +65,8 @@ static int jt_setup(int argc, char **argv); int fd = -1; -int connid = -1; +uint64_t conn_addr = -1; +uint64_t conn_cookie; char rawbuf[8192]; char *buf = rawbuf; int max = 8192; @@ -73,7 +77,8 @@ int rc = 0; do { \ memset(&data, 0, sizeof(data)); \ data.ioc_version = OBD_IOCTL_VERSION; \ - data.ioc_conn1 = connid; \ + data.ioc_addr = conn_addr; \ + data.ioc_cookie = conn_cookie; \ data.ioc_len = sizeof(data); \ if (fd < 0) { \ fprintf(stderr, "No device open, use device\n"); \ @@ -156,15 +161,9 @@ int getfd(char *func) return 0; } -#if 1 #define difftime(a, b) \ ((double)(a)->tv_sec - (b)->tv_sec + \ ((double)((a)->tv_usec - (b)->tv_usec) / 1000000)) -#else - -#define difftime(a, b) (((a)->tv_sec - (b)->tv_sec) + \ - (((a)->tv_usec - (b)->tv_usec) / 1000000)) -#endif static int be_verbose(int verbose, struct timeval *next_time, int num, int *next_num, int num_total) @@ -225,8 +224,8 @@ static int do_disconnect(char *func, int verbose) { struct obd_ioctl_data data; - if (connid == -1) - return 0; + if (conn_addr == -1) + return 0; IOCINIT(data); @@ -236,9 +235,9 @@ static int do_disconnect(char *func, int verbose) OBD_IOC_DISCONNECT, strerror(errno)); } else { if (verbose) - printf("%s: disconnected connid %d\n", cmdname(func), - connid); - connid = -1; + printf("%s: disconnected conn %Lx\n", cmdname(func), + conn_addr); + conn_addr = -1; } return rc; @@ -246,165 +245,348 @@ static int do_disconnect(char *func, int verbose) extern command_t cmdlist[]; -/* Given a XML document and the root of a mds branch do the setup */ +static int xml_command(char *cmd, ...) { + va_list args; + char *arg, *cmds[8]; + int i = 1, j; + + cmds[0] = cmd; + va_start(args, cmd); + + while (((arg = va_arg(args, char *)) != NULL) && (i < 8)) { + cmds[i] = arg; + i++; + } + + va_end(args); + + printf("obdctl > "); + for (j = 0; j < i; j++) + printf("%s ", cmds[j]); + + printf("\n"); + + return Parser_execarg(i, cmds, cmdlist); +} + +#if 0 +static network_t *xml_network(xmlDocPtr doc, xmlNodePtr root) { + xmlNodePtr cur = root->xmlChildrenNode; + network_t *net; + + if ((net = (network_t *)calloc(1, sizeof(network_t))) == NULL) { + printf("error: unable to malloc network_t\n"); + return NULL; + } + + net->type = xmlGetProp(root, "type"); + if (net->type == NULL) { + printf("error: type attrib required (tcp, elan, myrinet)\n"); + free(net); + return NULL; + } + + while (cur != NULL) { + if (!xmlStrcmp(cur->name, "server")) + net->server = xmlNodeGetContent(cur); + + if (!xmlStrcmp(cur->name, "port")) + net->port = atoi(xmlNodeGetContent(cur)); + + cur = cur->next; + } + + if (net->server == NULL) { + printf("error: tag required\n"); + free(net); + return NULL; + } + + return net; +} +#endif + static int xml_mds(xmlDocPtr doc, xmlNodePtr root, - char *serv_id, char *serv_uuid) { + char *serv_name, char *serv_uuid) { xmlNodePtr cur = root->xmlChildrenNode; char *fstype = NULL, *device = NULL; - char *newdev[1] = { "newdev" }; - char *attach[3] = { "attach", "mds", "MDSDEV" }; - char *setup[3] = { "setup", NULL, NULL }; int rc; + printf("--- Setting up MDS ---\n"); while (cur != NULL) { if (!xmlStrcmp(cur->name, "fstype")) - fstype = cur->content; + fstype = xmlNodeGetContent(cur); if (!xmlStrcmp(cur->name, "device")) - device = cur->content; + device = xmlNodeGetContent(cur); + + /* FIXME: Parse the network bits + * if (!xmlStrcmp(cur->name, "network")) { + * net = xml_network(doc, cur); + * if (net == NULL) + * return -1; + * } + * free(net); + */ + cur = cur->next; } - if ((fstype == NULL) || (device == NULL)) + if ((fstype == NULL) || (device == NULL)) { + printf("error: and tags required\n"); return -1; + } - /* Invoke commands as if passed interactively */ - rc = jt_newdev(1, newdev); - if (rc != 0) + if ((rc = xml_command("newdev", NULL)) != 0) return rc; - - rc = jt_attach(3, attach); - if (rc != 0) + + if ((rc = xml_command("attach","mds",serv_name,serv_uuid,NULL)) != 0) return rc; - setup[1] = device; - setup[2] = fstype; - rc = jt_setup(3, setup); - if (rc != 0) + if ((rc = xml_command("setup", device, fstype, NULL)) != 0) return rc; return 0; } -/* Given a XML document and the root of a obd branch do the setup */ static int xml_obd(xmlDocPtr doc, xmlNodePtr root, - char *serv_id, char *serv_uuid) { - /* FIXME: Fill in the guts... */ + char *serv_name, char *serv_uuid) { + char *obdtype, *format = NULL, *fstype = NULL, *device = NULL; + xmlNodePtr cur = root->xmlChildrenNode; + int rc; + + obdtype = xmlGetProp(root, "type"); + printf("--- Setting up OBD ---\n"); + + while (cur != NULL) { + if (!xmlStrcmp(cur->name, "fstype")) + fstype = xmlNodeGetContent(cur); + + if (!xmlStrcmp(cur->name, "device")) + device = xmlNodeGetContent(cur); + + if (!xmlStrcmp(cur->name, "autoformat")) + format = xmlNodeGetContent(cur); + + cur = cur->next; + } + + if ((obdtype == NULL) || (fstype == NULL) || (device == NULL)) { + printf("error: 'type' attrib and " + "and tags required\n"); + return -1; + } + + /* FIXME: Building and configuring loopback devices should go here + * but is currently unsupported. You'll have to use the scripts + * for now until support is added, or specify a real device. + */ + + if ((rc = xml_command("newdev", NULL)) != 0) + return rc; + + if ((rc = xml_command("attach", obdtype, + serv_name,serv_uuid, NULL)) != 0) + return rc; + + if ((rc = xml_command("setup", device, fstype, NULL)) != 0) + return rc; + return 0; } -/* Given a XML document and the root of a ost branch do the setup */ static int xml_ost(xmlDocPtr doc, xmlNodePtr root, - char *serv_id, char *serv_uuid) { - /* FIXME: Fill in the guts... */ + char *serv_name, char *serv_uuid) { + char *server_name = NULL, *server_uuid = NULL; + char *failover_name = NULL, *failover_uuid = NULL; + xmlNodePtr cur = root->xmlChildrenNode; + int server_num, failover_num, rc; + + printf("--- Setting up OST ---\n"); + while (cur != NULL) { + if (!xmlStrcmp(cur->name, "server_id")) { + server_num = atoi(xmlGetProp(cur, "num")); + server_name = xmlGetProp(cur, "name"); + server_uuid = xmlGetProp(cur, "uuid"); + } + + /* FIXME: Properly handle multiple failover servers */ + if (!xmlStrcmp(cur->name, "failover_id")) { + failover_num = atoi(xmlGetProp(cur, "num")); + failover_name = xmlGetProp(cur, "name"); + failover_uuid = xmlGetProp(cur, "uuid"); + } + + cur = cur->next; + } + + if ((server_name == NULL) || (server_uuid == NULL)) { + printf("error: atleast the tag is required\n"); + return -1; + } + + if ((rc = xml_command("newdev", NULL)) != 0) + return rc; + + if ((rc = xml_command("attach","ost",serv_name,serv_uuid,NULL)) != 0) + return rc; + + if ((rc = xml_command("setup", server_name, NULL)) != 0) + return rc; + return 0; } -/* Given a XML document and the root of a osc branch do the setup */ static int xml_osc(xmlDocPtr doc, xmlNodePtr root, - char *serv_id, char *serv_uuid) { + char *serv_name, char *serv_uuid) { + char *ost_name = NULL, *ost_uuid = NULL; xmlNodePtr cur = root->xmlChildrenNode; - char *type = NULL, *address = NULL; - char *newdev[1] = { "newdev" }; - char *attach[3] = { "attach", "osc", "OSCDEV" }; - char *setup[2] = { "setup", "-1" }; - int rc; + int ost_num, rc = 0; + printf("--- Setting up OSC ---\n"); while (cur != NULL) { - if (!xmlStrcmp(cur->name, "network")) { - type = xmlGetProp(cur, "type"); - if (type == NULL) - return -1; + if (!xmlStrcmp(cur->name, "service_id")) { + ost_num = atoi(xmlGetProp(cur, "num")); + ost_name = xmlGetProp(cur, "name"); + ost_uuid = xmlGetProp(cur, "uuid"); + } + + cur = cur->next; + } + + if ((ost_name == NULL) || (ost_uuid == NULL)) { + printf("error: atleast the tag is required\n"); + return -1; + } + + if ((rc = xml_command("newdev", NULL)) != 0) + return rc; + + if ((rc = xml_command("attach","osc",serv_name,serv_uuid,NULL)) != 0) + return rc; - address = xmlGetProp(cur, "address"); - if (address == NULL) - return -1; + if ((rc = xml_command("setup", ost_uuid, "localhost", NULL)) != 0) + return rc; - /* FIXME: Do the portals setup here as well? */ + return 0; +} + +static int xml_mdc(xmlDocPtr doc, xmlNodePtr root, + char *serv_name, char *serv_uuid) { + char *mds_name = NULL, *mds_uuid = NULL; + xmlNodePtr cur = root->xmlChildrenNode; + int mds_num, rc = 0; + + printf("--- Setting up MDC ---\n"); + while (cur != NULL) { + if (!xmlStrcmp(cur->name, "service_id")) { + mds_num = atoi(xmlGetProp(cur, "num")); + mds_name = xmlGetProp(cur, "name"); + mds_uuid = xmlGetProp(cur, "uuid"); } - + cur = cur->next; } - /* Invoke commands as if passed interactively */ - rc = jt_newdev(1, newdev); - if (rc != 0) - return rc; - - rc = jt_attach(2, attach); - if (rc != 0) + if ((mds_name == NULL) || (mds_uuid == NULL)) { + printf("error: atleast the tag is required\n"); + return -1; + } + + if ((rc = xml_command("newdev", NULL)) != 0) return rc; - - rc = jt_setup(1, setup); - if (rc != 0) + + if ((rc = xml_command("attach","mdc",serv_name,serv_uuid,NULL)) != 0) return rc; + if ((rc = xml_command("setup", mds_uuid, "localhost", NULL)) != 0) + return rc; + return 0; } -/* Given a XML document and the root of a lov branch do the setup */ static int xml_lov(xmlDocPtr doc, xmlNodePtr root, - char *serv_id, char *serv_uuid) { - /* FIXME: Fill in the guts... */ + char *serv_name, char *serv_uuid) { + printf("--- Setting up LOV ---\n"); return 0; } -/* Given a XML document and the root of a router branch do the setup */ static int xml_router(xmlDocPtr doc, xmlNodePtr root, - char *serv_id, char *serv_uuid) { - /* FIXME: Fill in the guts... */ + char *serv_name, char *serv_uuid) { + printf("--- Setting up ROUTER ---\n"); + return 0; +} + +static int xml_ldlm(xmlDocPtr doc, xmlNodePtr root, + char *serv_name, char *serv_uuid) { + int rc; + + printf("--- Setting up LDLM ---\n"); + if ((rc = xml_command("newdev", NULL)) != 0) + return rc; + + if ((rc = xml_command("attach","ldlm",serv_name,serv_uuid,NULL)) != 0) + return rc; + + if ((rc = xml_command("setup", NULL)) != 0) + return rc; + return 0; } -/* Given a XML document and service id/uuid setup the service */ static int xml_service(xmlDocPtr doc, xmlNodePtr root, - int serv_num, char *serv_id, char *serv_uuid) { + int serv_num, char *serv_name, char *serv_uuid) { xmlNodePtr cur = root; - char *id, *uuid; + char *name, *uuid; while (cur != NULL) { - id = xmlGetProp(cur, "id"); + name = xmlGetProp(cur, "name"); uuid = xmlGetProp(cur, "uuid"); - if (xmlStrcmp(id, serv_id) || + if (xmlStrcmp(name, serv_name) || xmlStrcmp(uuid, serv_uuid)) { cur = cur->next; continue; } if (!xmlStrcmp(cur->name, "mds")) - rc = xml_mds(doc, cur, serv_id, serv_uuid); + return xml_mds(doc, cur, name, uuid); else if (!xmlStrcmp(cur->name, "obd")) - rc = xml_obd(doc, cur, serv_id, serv_uuid); + return xml_obd(doc, cur, name, uuid); else if (!xmlStrcmp(cur->name, "ost")) - rc = xml_ost(doc, cur, serv_id, serv_uuid); + return xml_ost(doc, cur, name, uuid); else if (!xmlStrcmp(cur->name, "osc")) - rc = xml_osc(doc, cur, serv_id, serv_uuid); + return xml_osc(doc, cur, name, uuid); + else if (!xmlStrcmp(cur->name, "mdc")) + return xml_mdc(doc, cur, name, uuid); else if (!xmlStrcmp(cur->name, "lov")) - rc = xml_lov(doc, cur, serv_id, serv_uuid); + return xml_lov(doc, cur, name, uuid); else if (!xmlStrcmp(cur->name, "router")) - rc = xml_router(doc, cur, serv_id, serv_uuid); + return xml_router(doc, cur, name, uuid); + else if (!xmlStrcmp(cur->name, "ldlm")) + return xml_ldlm(doc, cur, name, uuid); else return -1; cur = cur->next; } - return rc; + printf("error: No XML config branch for name=%s uuid=%s\n", + serv_name, serv_uuid); + return -1; } -/* Given a XML document and profile id/uuid setup the profile */ static int xml_profile(xmlDocPtr doc, xmlNodePtr root, - int prof_num, char *prof_id, char *prof_uuid) { + int prof_num, char *prof_name, char *prof_uuid) { xmlNodePtr parent, cur = root; - char *id, *uuid; + char *name, *uuid, *srv_name, *srv_uuid; int rc = 0, num; while (cur != NULL) { - id = xmlGetProp(cur, "id"); + name = xmlGetProp(cur, "name"); uuid = xmlGetProp(cur, "uuid"); if (xmlStrcmp(cur->name, "profile") || - xmlStrcmp(id, prof_id) || + xmlStrcmp(name, prof_name) || xmlStrcmp(uuid, prof_uuid)) { cur = cur->next; continue; @@ -424,10 +606,12 @@ static int xml_profile(xmlDocPtr doc, xmlNodePtr root, if (!xmlStrcmp(cur->name, "service_id")) { num = atoi(xmlGetProp(cur, "num")); rc = xml_service(doc, root, num, - xmlGetProp(cur, "id"), - xmlGetProp(cur, "uuid")); - if (rc != 0) + srv_name = xmlGetProp(cur, "name"), + srv_uuid = xmlGetProp(cur, "uuid")); + if (rc != 0) { + printf("error: service config\n"); return rc; + } } cur = cur->next; @@ -441,7 +625,7 @@ static int xml_profile(xmlDocPtr doc, xmlNodePtr root, static int xml_node(xmlDocPtr doc, xmlNodePtr root) { xmlNodePtr parent, cur = root; - char *id, *uuid; + char *name, *uuid; int rc = 0, num; /* Walk the node tags looking for ours */ @@ -451,15 +635,15 @@ static int xml_node(xmlDocPtr doc, xmlNodePtr root) { continue; } - id = xmlGetProp(cur, "id"); - if (id == NULL) + name = xmlGetProp(cur, "name"); + if (name == NULL) return -1; uuid = xmlGetProp(cur, "uuid"); if (uuid == NULL) return -1; - /* FIXME: Verify our ID and UUID against /etc/lustre/id + /* FIXME: Verify our NAME and UUID against /etc/lustre/id * so we're sure we are who we think we are. */ @@ -473,7 +657,7 @@ static int xml_node(xmlDocPtr doc, xmlNodePtr root) { if (!xmlStrcmp(cur->name, "profile_id")) { num = atoi(xmlGetProp(cur, "num")); rc = xml_profile(doc, root, num, - xmlGetProp(cur, "id"), + xmlGetProp(cur, "name"), xmlGetProp(cur, "uuid")); if (rc != 0) return rc; @@ -517,7 +701,8 @@ static int do_xml(char *func, char *file) /* FIXME: Merge all the text nodes under each branch and * prune empty nodes. Just to make the parsing more - * tolerant. + * tolerant, the exact location of nested tags isn't + * critical for this. */ rc = xml_node(doc, cur->xmlChildrenNode); @@ -581,8 +766,8 @@ static int jt_connect(int argc, char **argv) fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]), OBD_IOC_CONNECT, strerror(rc = errno)); else - connid = data.ioc_conn1; - + conn_addr = data.ioc_addr; + conn_cookie = data.ioc_cookie; return rc; } @@ -593,6 +778,9 @@ static int jt_disconnect(int argc, char **argv) return -1; } + if (conn_addr == -1) + return 0; + return do_disconnect(argv[0], 0); } @@ -776,13 +964,44 @@ static int jt_newdev(int argc, char **argv) return rc; } +static int jt_list(int argc, char **argv) +{ + char buf[1024]; + struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; + + if (getfd(argv[0])) + return -1; + + memset(buf, 0, sizeof(buf)); + data->ioc_version = OBD_IOCTL_VERSION; + data->ioc_addr = conn_addr; + data->ioc_cookie = conn_addr; + data->ioc_len = sizeof(buf); + data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); + + if (argc != 1) { + fprintf(stderr, "usage: %s\n", cmdname(argv[0])); + return -1; + } + + rc = ioctl(fd, OBD_IOC_LIST , data); + if (rc < 0) + fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), + strerror(rc=errno)); + else { + printf("%s", data->ioc_bulk); + } + + return rc; +} + static int jt_attach(int argc, char **argv) { struct obd_ioctl_data data; IOCINIT(data); - if (argc != 2 && argc != 3) { + if (argc != 2 && argc != 3 && argc != 4) { fprintf(stderr, "usage: %s type [name [uuid]]\n", cmdname(argv[0])); return -1; @@ -790,11 +1009,16 @@ static int jt_attach(int argc, char **argv) data.ioc_inllen1 = strlen(argv[1]) + 1; data.ioc_inlbuf1 = argv[1]; - if (argc == 3) { + if (argc >= 3) { data.ioc_inllen2 = strlen(argv[2]) + 1; data.ioc_inlbuf2 = argv[2]; } + if (argc == 4) { + data.ioc_inllen3 = strlen(argv[3]) + 1; + data.ioc_inlbuf3 = argv[3]; + } + if (obd_ioctl_pack(&data, &buf, max)) { fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); return -2; @@ -1127,7 +1351,6 @@ static int jt_test_brw(int argc, char **argv) return -2; } IOCINIT(data); - data.ioc_conn2 = connid; data.ioc_obdo1.o_id = 2; data.ioc_count = len; data.ioc_offset = 0; @@ -1199,6 +1422,71 @@ static int jt_test_brw(int argc, char **argv) return rc; } +static int jt_lov_config(int argc, char **argv) +{ + struct obd_ioctl_data data; + struct lov_desc desc; + uuid_t *uuidarray; + int size, i; + IOCINIT(data); + + if (argc <= 5 ){ + Parser_printhelp("lovconfig"); + return -1; + } + + if (strlen(argv[1]) > sizeof(uuid_t) - 1) { + fprintf(stderr, "lov_config: no %dB memory for uuid's\n", + size); + return -ENOMEM; + } + + memset(&desc, 0, sizeof(desc)); + strcpy(desc.ld_uuid, argv[1]); + desc.ld_default_stripecount = strtoul(argv[2], NULL, 0); + desc.ld_default_stripesize = strtoul(argv[3], NULL, 0); + desc.ld_pattern = strtoul(argv[4], NULL, 0); + desc.ld_tgt_count = argc - 5; + + + size = sizeof(uuid_t) * desc.ld_tgt_count; + uuidarray = malloc(size); + if (!uuidarray) { + fprintf(stderr, "lov_config: no %dB memory for uuid's\n", + size); + return -ENOMEM; + } + memset(uuidarray, 0, size); + for (i=5 ; i < argc ; i++) { + char *buf = (char *) (uuidarray + i -5 ); + if (strlen(argv[i]) >= sizeof(uuid_t)) { + fprintf(stderr, "lov_config: arg %d (%s) too long\n", + i, argv[i]); + free(uuidarray); + return -EINVAL; + } + strcpy(buf, argv[i]); + } + + data.ioc_inllen1 = sizeof(desc); + data.ioc_inlbuf1 = (char *)&desc; + data.ioc_inllen2 = size; + data.ioc_inlbuf2 = (char *)uuidarray; + + if (obd_ioctl_pack(&data, &buf, max)) { + fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); + return -EINVAL; + } + + rc = ioctl(fd, OBD_IOC_LOV_CONFIG , buf); + if (rc < 0) + fprintf(stderr, "lov_config: error: %s: %s\n", + cmdname(argv[0]),strerror(rc = errno)); + free(uuidarray); + return rc; +} + + static int jt_test_ldlm(int argc, char **argv) { struct obd_ioctl_data data; @@ -1249,6 +1537,9 @@ command_t cmdlist[] = { "--threads "}, /* Device configuration commands */ + {"lovconfig", jt_lov_config, 0, "configure lov data on MDS " + "(usage: lov-uuid stripecount, stripesize, pattern, UUID1, [UUID2, ...])"}, + {"list", jt_list, 0, "list the devices (no args)"}, {"newdev", jt_newdev, 0, "set device to a new unused obd (no args)"}, {"device", jt_device, 0, "set current device (args device_no name)"}, {"name2dev", jt_name2dev, 0, "set device by name (args name)"},