/* * Callback function which builds an iSNS object from the * list of attr=tag values. */ static int __isns_local_registry_load_object(const char *line, int argc, char **argv, void *user_data) { isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT; struct isns_attr_list_parser state; isns_object_list_t *list = user_data; isns_object_t *obj, *entity = NULL; for (; argc > 0; --argc) { char *attr = argv[argc-1]; if (!strncasecmp(attr, "owner=", 6)) { char *eid = __isns_local_registry_entity_name(attr + 6); ISNS_QUICK_ATTR_LIST_DECLARE(key_attrs, ISNS_TAG_ENTITY_IDENTIFIER, string, eid); if (entity) { isns_error("Duplicate owner entry in registry\n"); continue; } isns_attr_print(&key_attrs.iqa_attr, isns_print_stdout); entity = isns_object_list_lookup(list, &isns_entity_template, &key_attrs.iqa_list); if (entity != NULL) continue; isns_debug_state("Creating fake entity %s\n", eid); entity = isns_create_entity(ISNS_ENTITY_PROTOCOL_ISCSI, eid); isns_object_list_append(list, entity); } else { break; } } isns_attr_list_parser_init(&state, NULL); if (!isns_parse_attrs(argc, argv, &attrs, &state)) { isns_error("Unable to parse attrs\n"); isns_attr_list_destroy(&attrs); return 0; } obj = isns_create_object(isns_attr_list_parser_context(&state), &attrs, entity); isns_attr_list_destroy(&attrs); if (obj == NULL) { isns_error("Unable to create object\n"); return 0; } isns_object_list_append(list, obj); return 1; }
/* * Handle discovery domain registration/deregistration */ int parse_dd_registration(char **argv, int argc, isns_attr_list_t *keys) { struct isns_attr_list_parser state; isns_attr_list_parser_init(&state, &isns_dd_template); if (argc == 1 && !strcmp(argv[0], "help")) { printf("Object query:\n" " isnsadm --dd-register attr=value attr=value ...\n" "You cannot specify more than one domain.\n" "If you want to modify an existing domain, you must specify its ID.\n" "The following attributes are recognized:\n"); isns_attr_list_parser_help(&state); exit(0); } return isns_parse_attrs(argc, argv, keys, &state); }
int register_objects(isns_client_t *clnt, int argc, char **argv) { isns_object_list_t objects = ISNS_OBJECT_LIST_INIT; isns_object_t *key_obj = NULL; uint32_t status; if (opt_key != NULL) { isns_attr_list_t key_attrs = ISNS_ATTR_LIST_INIT; struct isns_attr_list_parser state; isns_attr_list_parser_init(&state, NULL); if (!isns_parse_attrs(1, &opt_key, &key_attrs, &state)) { isns_error("Cannot parse registration key \"%s\"\n", opt_key); return 0; } key_obj = isns_create_object(isns_attr_list_parser_context(&state), &key_attrs, NULL); isns_attr_list_destroy(&key_attrs); if (!key_obj) { isns_error("Cannot create registration key object\n"); return 0; } } else { /* If the user does not provide a key object, * create/update an entity. */ key_obj = isns_create_entity(ISNS_ENTITY_PROTOCOL_ISCSI, NULL); } if (!parse_registration(argv, argc, &objects, key_obj)) isns_fatal("Unable to parse registration\n"); status = __register_objects(clnt, key_obj, &objects); isns_object_list_destroy(&objects); isns_object_release(key_obj); return status; }
int parse_dd_deregistration(char **argv, int argc, uint32_t *dd_id, isns_attr_list_t *keys) { struct isns_attr_list_parser state; isns_attr_list_parser_init(&state, &isns_dd_template); if (argc == 0 || (argc == 1 && !strcmp(argv[0], "help"))) { printf("DD deregistration:\n" " isnsadm --dd-deregister dd-id attr=value attr=value ...\n" "You cannot specify more than one domain.\n" "The following attributes are recognized:\n"); isns_attr_list_parser_help(&state); exit(0); } *dd_id = parse_count(argv[0]); return isns_parse_attrs(argc - 1, argv + 1, keys, &state); }
/* * Parse the deregistration string given by the user * * 5.6.5.2 * The Message Key may contain key or non-key attributes or no * attributes at all. If multiple attributes are used as the * Message Key, then they MUST all be from the same object type * (e.g., IP address and TCP/UDP Port are attributes of the * Portal object type). */ int parse_deregistration(char **argv, int argc, isns_attr_list_t *keys) { struct isns_attr_list_parser state; isns_attr_list_parser_init(&state, NULL); state.multi_type_permitted = 1; state.nil_permitted = 1; if (argc == 1 && !strcmp(argv[0], "help")) { printf("Object deregistration:\n" " isnsadm --deregister attr=value attr=value ...\n" "All attributes must refer to a common object type.\n" "\nThe following attributes are recognized:\n"); isns_attr_list_parser_help(&state); exit(0); } return isns_parse_attrs(argc, argv, keys, &state); }
/* * Parse a policy */ int parse_policy(int argc, char **argv, isns_attr_list_t *attrs, const char *help_title, const char *help_action) { struct isns_attr_list_parser state; isns_attr_list_parser_init(&state, &isns_policy_template); state.nil_permitted = 0; state.load_key = load_key_callback; state.generate_key = generate_key_callback; if (argc == 1 && !strcmp(argv[0], "help")) { printf("%s:\n" " isnsadm %s attr=value attr=value ...\n" "Specifying a Security Policy Index is mandatory.\n" "\nThe following attributes are recognized:\n", help_title, help_action); isns_attr_list_parser_help(&state); exit(0); } return isns_parse_attrs(argc, argv, attrs, &state); }
/* * Parse the list query string given by the user */ int parse_list(int argc, char **argv, isns_object_template_t **type_p, isns_attr_list_t *keys) { struct isns_attr_list_parser state; isns_object_template_t *query_type = NULL; char *type_name; if (argc == 0) usage(1, "Missing object type"); if (argc == 1 && !strcmp(argv[0], "help")) { printf("Object query:\n" " isnsadm --list type attr=value attr=value ...\n" "Possible value for <type>:\n" " entities - list all network entites\n" " nodes - list all storage nodes\n" " portals - list all portals\n" " portal-groups - list all portal groups\n" " dds - list all discovery domains\n" " ddsets - list all discovery domains sets\n" " policies - list all policies (privileged)\n" "Additional attributes can be specified to scope the\n" "search. They must match the specified object type.\n" "\nThe following attributes are recognized:\n"); isns_attr_list_parser_help(NULL); exit(0); } type_name = *argv++; --argc; if (!strcasecmp(type_name, "entities")) query_type = &isns_entity_template; else if (!strcasecmp(type_name, "nodes")) query_type = &isns_iscsi_node_template; else if (!strcasecmp(type_name, "portals")) query_type = &isns_portal_template; else if (!strcasecmp(type_name, "portal-groups")) query_type = &isns_iscsi_pg_template; else if (!strcasecmp(type_name, "dds")) query_type = &isns_dd_template; else if (!strcasecmp(type_name, "ddsets")) query_type = &isns_ddset_template; else if (!strcasecmp(type_name, "policies")) query_type = &isns_policy_template; else { isns_error("Unknown object type \"%s\"\n", type_name); return 0; } *type_p = query_type; isns_attr_list_parser_init(&state, query_type); state.nil_permitted = 1; return isns_parse_attrs(argc, argv, keys, &state); }
int parse_registration(char **argv, int argc, isns_object_list_t *objs, isns_object_t *key_obj) { struct sockaddr_storage def_addr; isns_object_t *entity = NULL, *last_portal = NULL, *last_node = NULL; const char *def_port = NULL; int i; if (argc == 1 && !strcmp(argv[0], "help")) { printf("Object registration:\n" " isnsadm [-key attr=value] --register type,attr=value,... type,attr=value,...\n" "Where type can be one of:\n" " entity create/update network entity\n" " initiator create iSCSI initiator storage node\n" " target create iSCSI target storage node\n" " control create control node\n" " portal create portal\n" " pg create portal group\n" "\nThe following attributes are recognized:\n"); isns_attr_list_parser_help(NULL); exit(0); } if (argc == 0) usage(1, "Missing object list\n"); if (key_obj) { //isns_object_list_append(objs, key_obj); if (isns_object_is_entity(key_obj)) entity = key_obj; } def_addr = opt_myaddr; for (i = 0; i < argc; ++i) { isns_attr_list_t attrlist = ISNS_ATTR_LIST_INIT; struct isns_attr_list_parser state; isns_object_t *obj; char *type, *name, *value, *next_attr; char *attrs[128]; unsigned int nattrs = 0; name = argv[i]; if ((next_attr = strchr(name, ',')) != NULL) *next_attr++ = '\0'; while (next_attr && *next_attr) { if (nattrs > 128) isns_fatal("Too many attributes\n"); /* Show mercy with fat fingered * people,,,,who,cannot,,,type,properly */ if (next_attr[0] != ',') attrs[nattrs++] = next_attr; if ((next_attr = strchr(next_attr, ',')) != NULL) *next_attr++ = '\0'; } if ((value = strchr(name, '=')) != NULL) *value++ = '\0'; type = name; if (!strcmp(name, "entity")) { if (entity == NULL) { isns_error("Cannot create entity object " "within this key object\n"); return 0; } if (value != NULL) isns_object_set_string(entity, ISNS_TAG_ENTITY_IDENTIFIER, value); obj = isns_object_get(entity); goto handle_attributes; } else if (!strcmp(name, "node") || !strcmp(name, "initiator")) { const char *node_name; node_name = isns_config.ic_source_name; if (value) node_name = value; obj = isns_create_storage_node(node_name, ISNS_ISCSI_INITIATOR_MASK, entity); last_node = obj; isns_addr_set_port((struct sockaddr *) &def_addr, ISNS_DEFAULT_PORT_INITIATOR); def_port = "iscsi"; } else if (!strcmp(name, "target")) { const char *node_name; node_name = isns_config.ic_source_name; if (value) node_name = value; obj = isns_create_storage_node(node_name, ISNS_ISCSI_TARGET_MASK, entity); last_node = obj; isns_addr_set_port((struct sockaddr *) &def_addr, ISNS_DEFAULT_PORT_TARGET); def_port = "iscsi-target"; } else if (!strcmp(name, "control")) { const char *node_name; node_name = isns_config.ic_control_name; if (value) node_name = value; obj = isns_create_storage_node(node_name, ISNS_ISCSI_CONTROL_MASK, entity); last_node = obj; def_port = NULL; } else if (!strcmp(name, "portal")) { isns_portal_info_t portal_info; if (value == NULL) { if (def_port == NULL) isns_fatal("portal must follow initiator or target\n"); isns_portal_init(&portal_info, (struct sockaddr *) &def_addr, IPPROTO_TCP); } else if (!isns_portal_parse(&portal_info, value, def_port)) isns_fatal("Unable to parse portal=%s\n", value); obj = isns_create_portal(&portal_info, entity); last_portal = obj; } else if (!strcmp(name, "pg")) { if (value) isns_fatal("Unexpected value for portal group\n"); if (!last_portal || !last_node) isns_fatal("Portal group registration must follow portal and node\n"); obj = isns_create_portal_group(last_portal, last_node, 10); } else { isns_error("Unknown object type \"%s\"\n", name); return 0; } if (obj == NULL) { isns_error("Failure to create %s object\n", name); return 0; } isns_object_list_append(objs, obj); handle_attributes: isns_attr_list_parser_init(&state, obj->ie_template); state.default_port = def_port; if (!isns_parse_attrs(nattrs, attrs, &attrlist, &state) || !isns_object_set_attrlist(obj, &attrlist)) { isns_error("Failure to set all %s attributes\n", name); isns_attr_list_destroy(&attrlist); return 0; } isns_attr_list_destroy(&attrlist); isns_object_release(obj); } return 1; }