1/*- 2 * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sbin/geom/core/geom.c 162867 2006-09-30 14:39:18Z pjd $"); |
29 30#include <sys/param.h> 31#include <sys/linker.h> 32#include <sys/module.h> 33#include <sys/stat.h> 34#include <sys/sysctl.h> 35#include <ctype.h> 36#include <err.h> --- 33 unchanged lines hidden (view full) --- 70 71struct g_command std_commands[] = { 72 { "help", 0, std_help, G_NULL_OPTS, NULL }, 73 { "list", 0, std_list, G_NULL_OPTS, 74 "[name ...]" 75 }, 76 { "status", 0, std_status, 77 { |
78 { 's', "script", NULL, G_TYPE_BOOL }, |
79 G_OPT_SENTINEL 80 }, 81 "[-s] [name ...]" 82 }, 83 { "load", G_FLAG_VERBOSE | G_FLAG_LOADKLD, std_load, G_NULL_OPTS, NULL }, 84 { "unload", G_FLAG_VERBOSE, std_unload, G_NULL_OPTS, NULL }, 85 G_CMD_SENTINEL 86}; --- 10 unchanged lines hidden (view full) --- 97 return; 98 } 99 if ((cmd->gc_flags & G_FLAG_VERBOSE) != 0) 100 fprintf(stderr, " [-v]"); 101 for (i = 0; ; i++) { 102 opt = &cmd->gc_options[i]; 103 if (opt->go_name == NULL) 104 break; |
105 if (opt->go_val != NULL || G_OPT_TYPE(opt) == G_TYPE_BOOL) |
106 fprintf(stderr, " ["); 107 else 108 fprintf(stderr, " "); 109 fprintf(stderr, "-%c", opt->go_char); |
110 if (G_OPT_TYPE(opt) != G_TYPE_BOOL) |
111 fprintf(stderr, " %s", opt->go_name); |
112 if (opt->go_val != NULL || G_OPT_TYPE(opt) == G_TYPE_BOOL) |
113 fprintf(stderr, "]"); 114 } 115 fprintf(stderr, "\n"); 116} 117 118static void 119usage(void) 120{ --- 92 unchanged lines hidden (view full) --- 213 214/* 215 * Add given option to gctl_req. 216 */ 217static void 218set_option(struct gctl_req *req, struct g_option *opt, const char *val) 219{ 220 |
221 if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) { |
222 intmax_t number; 223 224 errno = 0; 225 number = strtoimax(optarg, NULL, 0); 226 if (errno != 0) { 227 err(EXIT_FAILURE, "Invalid value for '%c' argument.", 228 opt->go_char); 229 } 230 opt->go_val = malloc(sizeof(intmax_t)); 231 if (opt->go_val == NULL) 232 errx(EXIT_FAILURE, "No memory."); 233 *(intmax_t *)opt->go_val = number; 234 235 gctl_ro_param(req, opt->go_name, sizeof(intmax_t), opt->go_val); |
236 } else if (G_OPT_TYPE(opt) == G_TYPE_STRING) { |
237 gctl_ro_param(req, opt->go_name, -1, optarg); |
238 } else if (G_OPT_TYPE(opt) == G_TYPE_BOOL) { |
239 opt->go_val = malloc(sizeof(int)); 240 if (opt->go_val == NULL) 241 errx(EXIT_FAILURE, "No memory."); 242 *(int *)opt->go_val = *val - '0'; 243 244 gctl_ro_param(req, opt->go_name, sizeof(int), 245 opt->go_val); |
246 } else { 247 assert(!"Invalid type"); |
248 } 249} 250 251/* 252 * 1. Add given argument by caller. 253 * 2. Add default values of not given arguments. 254 * 3. Add the rest of arguments. 255 */ --- 8 unchanged lines hidden (view full) --- 264 265 *opts = '\0'; 266 if ((cmd->gc_flags & G_FLAG_VERBOSE) != 0) 267 strlcat(opts, "v", sizeof(opts)); 268 for (i = 0; ; i++) { 269 opt = &cmd->gc_options[i]; 270 if (opt->go_name == NULL) 271 break; |
272 assert(G_OPT_TYPE(opt) != 0); 273 assert((opt->go_type & ~G_TYPE_MASK) == 0); |
274 strlcatf(opts, sizeof(opts), "%c", opt->go_char); |
275 if (G_OPT_TYPE(opt) != G_TYPE_BOOL) |
276 strlcat(opts, ":", sizeof(opts)); 277 } 278 279 /* 280 * Add specified arguments. 281 */ 282 while ((ch = getopt(*argc, *argv, opts)) != -1) { 283 /* Standard (not passed to kernel) options. */ 284 switch (ch) { 285 case 'v': 286 verbose = 1; 287 continue; 288 } 289 /* Options passed to kernel. */ 290 opt = find_option(cmd, ch); 291 if (opt == NULL) 292 usage(); 293 if (G_OPT_ISDONE(opt)) { |
294 warnx("Option '%c' specified twice.", opt->go_char); |
295 usage(); 296 } 297 G_OPT_DONE(opt); 298 |
299 if (G_OPT_TYPE(opt) == G_TYPE_BOOL) |
300 set_option(req, opt, "1"); 301 else 302 set_option(req, opt, optarg); 303 } 304 *argc -= optind; 305 *argv += optind; 306 307 /* 308 * Add not specified arguments, but with default values. 309 */ 310 for (i = 0; ; i++) { 311 opt = &cmd->gc_options[i]; 312 if (opt->go_name == NULL) 313 break; 314 if (G_OPT_ISDONE(opt)) 315 continue; 316 |
317 if (G_OPT_TYPE(opt) == G_TYPE_BOOL) { |
318 assert(opt->go_val == NULL); 319 set_option(req, opt, "0"); 320 } else { 321 if (opt->go_val == NULL) { |
322 warnx("Option '%c' not specified.", |
323 opt->go_char); 324 usage(); 325 } else { |
326 if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) { |
327 gctl_ro_param(req, opt->go_name, 328 sizeof(intmax_t), opt->go_val); |
329 } else if (G_OPT_TYPE(opt) == G_TYPE_STRING) { |
330 gctl_ro_param(req, opt->go_name, -1, 331 opt->go_val); |
332 } else { 333 assert(!"Invalid type"); |
334 } 335 } 336 } 337 } 338 /* 339 * Add rest of given arguments. 340 */ 341 gctl_ro_param(req, "nargs", sizeof(int), argc); --- 64 unchanged lines hidden (view full) --- 406 char buf[4096]; 407 408 /* First try to find a command defined by a class. */ 409 cmd = find_command(argv[0], GEOM_CLASS_CMDS); 410 if (cmd == NULL) { 411 /* Now, try to find a standard command. */ 412 cmd = find_command(argv[0], GEOM_STD_CMDS); 413 if (cmd == NULL) { |
414 warnx("Unknown command: %s.", argv[0]); |
415 usage(); 416 } 417 if (!std_available(cmd->gc_name)) { |
418 warnx("Command '%s' not available.", argv[0]); |
419 exit(EXIT_FAILURE); 420 } 421 } 422 if ((cmd->gc_flags & G_FLAG_LOADKLD) != 0) 423 load_module(); 424 425 req = gctl_get_handle(); 426 gctl_ro_param(req, "class", -1, gclass_name); --- 9 unchanged lines hidden (view full) --- 436 flags = set_flags(cmd); 437 cmd->gc_func(req, flags); 438 errstr = req->error; 439 } else { 440 gctl_rw_param(req, "output", sizeof(buf), buf); 441 errstr = gctl_issue(req); 442 } 443 if (errstr != NULL && errstr[0] != '\0') { |
444 warnx("%s", errstr); |
445 if (strncmp(errstr, "warning: ", strlen("warning: ")) != 0) { 446 gctl_free(req); 447 exit(EXIT_FAILURE); 448 } 449 } 450 if (buf[0] != '\0') 451 printf("%s", buf); 452 gctl_free(req); --- 32 unchanged lines hidden (view full) --- 485 } 486 err(EXIT_FAILURE, "Cannot access library"); 487 } 488 dlh = dlopen(path, RTLD_NOW); 489 if (dlh == NULL) 490 errx(EXIT_FAILURE, "Cannot open library: %s.", dlerror()); 491 lib_version = dlsym(dlh, "lib_version"); 492 if (lib_version == NULL) { |
493 warnx("Cannot find symbol %s: %s.", "lib_version", dlerror()); |
494 dlclose(dlh); 495 exit(EXIT_FAILURE); 496 } 497 if (*lib_version != G_LIB_VERSION) { 498 dlclose(dlh); 499 errx(EXIT_FAILURE, "%s and %s are not synchronized.", 500 getprogname(), path); 501 } 502 version = dlsym(dlh, "version"); 503 if (version == NULL) { |
504 warnx("Cannot find symbol %s: %s.", "version", dlerror()); |
505 dlclose(dlh); 506 exit(EXIT_FAILURE); 507 } 508 class_commands = dlsym(dlh, "class_commands"); 509 if (class_commands == NULL) { |
510 warnx("Cannot find symbol %s: %s.", "class_commands", 511 dlerror()); |
512 dlclose(dlh); 513 exit(EXIT_FAILURE); 514 } 515} 516 517/* 518 * Class name should be all capital letters. 519 */ --- 165 unchanged lines hidden (view full) --- 685static int 686std_list_available(void) 687{ 688 struct gmesh mesh; 689 struct gclass *classp; 690 int error; 691 692 error = geom_gettree(&mesh); |
693 if (error != 0) 694 errc(EXIT_FAILURE, error, "Cannot get GEOM tree"); |
695 classp = find_class(&mesh, gclass_name); 696 geom_deletetree(&mesh); 697 if (classp != NULL) 698 return (1); 699 return (0); 700} 701 702static void 703std_list(struct gctl_req *req, unsigned flags __unused) 704{ 705 struct gmesh mesh; 706 struct gclass *classp; 707 struct ggeom *gp; 708 const char *name; 709 int error, i, nargs; 710 711 error = geom_gettree(&mesh); |
712 if (error != 0) 713 errc(EXIT_FAILURE, error, "Cannot get GEOM tree"); |
714 classp = find_class(&mesh, gclass_name); 715 if (classp == NULL) { 716 geom_deletetree(&mesh); |
717 warnx("Class %s not found.", gclass_name); |
718 return; 719 } 720 nargs = gctl_get_int(req, "nargs"); 721 if (nargs > 0) { 722 for (i = 0; i < nargs; i++) { 723 name = gctl_get_ascii(req, "arg%d", i); 724 gp = find_geom(classp, name); 725 if (gp != NULL) 726 list_one_geom(gp); 727 else |
728 warnx("No such geom: %s.", name); |
729 } 730 } else { 731 LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { 732 if (LIST_EMPTY(&gp->lg_provider)) 733 continue; 734 list_one_geom(gp); 735 } 736 } --- 103 unchanged lines hidden (view full) --- 840 struct gmesh mesh; 841 struct gclass *classp; 842 struct ggeom *gp; 843 const char *name; 844 int name_len, status_len; 845 int error, i, n, nargs, script; 846 847 error = geom_gettree(&mesh); |
848 if (error != 0) 849 errc(EXIT_FAILURE, error, "Cannot get GEOM tree"); |
850 classp = find_class(&mesh, gclass_name); 851 if (classp == NULL) { |
852 warnx("Class %s not found.", gclass_name); |
853 goto end; 854 } 855 nargs = gctl_get_int(req, "nargs"); 856 script = gctl_get_int(req, "script"); 857 name_len = strlen("Name"); 858 status_len = strlen("Status"); 859 if (nargs > 0) { 860 for (i = 0, n = 0; i < nargs; i++) { 861 name = gctl_get_ascii(req, "arg%d", i); 862 gp = find_geom(classp, name); 863 if (gp == NULL) |
864 warnx("No such geom: %s.", name); |
865 else { 866 status_update_len(gp, &name_len, &status_len); 867 n++; 868 } 869 } 870 if (n == 0) 871 goto end; 872 } else { --- 124 unchanged lines hidden --- |