📄 dmsetup.c
字号:
r = 1;out: if (len) dm_free(options); return r;}/* * List devices */static int _ls(int argc, char **argv, void *data){ if ((_switches[TARGET_ARG] && _target) || (_switches[EXEC_ARG] && _command)) return _status(argc, argv, data); else if ((_switches[TREE_ARG])) return _display_tree(argc, argv, data); else return _process_all(argc, argv, 0, _display_name);}static int _help(int argc, char **argv, void *data);/* * Dispatch table */static struct command _commands[] = { {"help", "[-c|-C|--columns]", 0, 0, _help}, {"create", "<dev_name> [-j|--major <major> -m|--minor <minor>]\n" "\t [-U|--uid <uid>] [-G|--gid <gid>] [-M|--mode <octal_mode>]\n" "\t [-u|uuid <uuid>]\n" "\t [--notable | --table <table> | <table_file>]", 1, 2, _create}, {"remove", "[-f|--force] <device>", 0, 1, _remove}, {"remove_all", "[-f|--force]", 0, 0, _remove_all}, {"suspend", "[--noflush] <device>", 0, 1, _suspend}, {"resume", "<device>", 0, 1, _resume}, {"load", "<device> [<table_file>]", 0, 2, _load}, {"clear", "<device>", 0, 1, _clear}, {"reload", "<device> [<table_file>]", 0, 2, _load}, {"rename", "<device> <new_name>", 1, 2, _rename}, {"message", "<device> <sector> <message>", 2, -1, _message}, {"ls", "[--target <target_type>] [--exec <command>] [--tree [-o options]]", 0, 0, _ls}, {"info", "[<device>]", 0, 1, _info}, {"deps", "[<device>]", 0, 1, _deps}, {"status", "[<device>] [--target <target_type>]", 0, 1, _status}, {"table", "[<device>] [--target <target_type>] [--showkeys]", 0, 1, _status}, {"wait", "<device> [<event_nr>]", 0, 2, _wait}, {"mknodes", "[<device>]", 0, 1, _mknodes}, {"targets", "", 0, 0, _targets}, {"version", "", 0, 0, _version}, {"setgeometry", "<device> <cyl> <head> <sect> <start>", 5, 5, _setgeometry}, {NULL, NULL, 0, 0, NULL}};static void _usage(FILE *out){ int i; fprintf(out, "Usage:\n\n"); fprintf(out, "dmsetup [--version] [-v|--verbose [-v|--verbose ...]]\n" " [-r|--readonly] [--noopencount] [--nolockfs]\n" " [-c|-C|--columns] [-o <fields>] [-O|--sort <sort_fields>]\n" " [--noheadings] [--separator <separator>]\n\n"); for (i = 0; _commands[i].name; i++) fprintf(out, "\t%s %s\n", _commands[i].name, _commands[i].help); fprintf(out, "\n<device> may be device name or -u <uuid> or " "-j <major> -m <minor>\n"); fprintf(out, "<fields> are comma-separated. Use 'help -c' for list.\n"); fprintf(out, "Table_file contents may be supplied on stdin.\n"); fprintf(out, "Tree options are: ascii, utf, vt100; compact, inverted, notrunc;\n" " [no]device, active, open, rw and uuid.\n"); fprintf(out, "\n"); return;}static void _losetup_usage(FILE *out){ fprintf(out, "Usage:\n\n"); fprintf(out, "losetup [-d|-a] [-e encryption] " "[-o offset] [-f|loop_device] [file]\n\n");}static int _help(int argc __attribute((unused)), char **argv __attribute((unused)), void *data __attribute((unused))){ _usage(stderr); if (_switches[COLS_ARG]) { _switches[OPTIONS_ARG] = 1; _string_args[OPTIONS_ARG] = (char *) "help"; _switches[SORT_ARG] = 0; (void) _report_init(NULL); } return 1;}static struct command *_find_command(const char *name){ int i; for (i = 0; _commands[i].name; i++) if (!strcmp(_commands[i].name, name)) return _commands + i; return NULL;}static int _process_tree_options(const char *options){ const char *s, *end; struct winsize winsz; size_t len; /* Symbol set default */ if (!strcmp(nl_langinfo(CODESET), "UTF-8")) _tsym = &_tsym_utf; else _tsym = &_tsym_ascii; /* Default */ _tree_switches[TR_DEVICE] = 1; _tree_switches[TR_TRUNCATE] = 1; /* parse */ for (s = options; s && *s; s++) { len = 0; for (end = s; *end && *end != ','; end++, len++) ; if (!strncmp(s, "device", len)) _tree_switches[TR_DEVICE] = 1; else if (!strncmp(s, "nodevice", len)) _tree_switches[TR_DEVICE] = 0; else if (!strncmp(s, "status", len)) _tree_switches[TR_STATUS] = 1; else if (!strncmp(s, "table", len)) _tree_switches[TR_TABLE] = 1; else if (!strncmp(s, "active", len)) _tree_switches[TR_ACTIVE] = 1; else if (!strncmp(s, "open", len)) _tree_switches[TR_OPENCOUNT] = 1; else if (!strncmp(s, "uuid", len)) _tree_switches[TR_UUID] = 1; else if (!strncmp(s, "rw", len)) _tree_switches[TR_RW] = 1; else if (!strncmp(s, "utf", len)) _tsym = &_tsym_utf; else if (!strncmp(s, "vt100", len)) _tsym = &_tsym_vt100; else if (!strncmp(s, "ascii", len)) _tsym = &_tsym_ascii; else if (!strncmp(s, "inverted", len)) _tree_switches[TR_BOTTOMUP] = 1; else if (!strncmp(s, "compact", len)) _tree_switches[TR_COMPACT] = 1; else if (!strncmp(s, "notrunc", len)) _tree_switches[TR_TRUNCATE] = 0; else { fprintf(stderr, "Tree options not recognised: %s\n", s); return 0; } if (!*end) break; s = end; } /* Truncation doesn't work well with vt100 drawing char */ if (_tsym != &_tsym_vt100) if (ioctl(1, (unsigned long) TIOCGWINSZ, &winsz) >= 0 && winsz.ws_col > 3) _termwidth = winsz.ws_col - 3; return 1;}/* * Returns the full absolute path, or NULL if the path could * not be resolved. */static char *_get_abspath(char *path){ char *_path;#ifdef HAVE_CANONICALIZE_FILE_NAME _path = canonicalize_file_name(path);#else /* FIXME Provide alternative */#endif return _path;}static char *parse_loop_device_name(char *dev){ char *buf; char *device; if (!(buf = dm_malloc(PATH_MAX))) return NULL; if (dev[0] == '/') { if (!(device = _get_abspath(dev))) goto error; if (strncmp(device, DEV_PATH, strlen(DEV_PATH))) goto error; strncpy(buf, strrchr(device, '/') + 1, (size_t) PATH_MAX); dm_free(device); } else { /* check for device number */ if (!strncmp(dev, "loop", strlen("loop"))) strncpy(buf, dev, (size_t) PATH_MAX); else goto error; } return buf;error: return NULL;}/* * create a table for a mapped device using the loop target. */static int _loop_table(char *table, size_t tlen, char *file, char *dev __attribute((unused)), off_t off){ struct stat fbuf; off_t size, sectors; int fd = -1;#ifdef HAVE_SYS_STATVFS_H struct statvfs fsbuf; off_t blksize;#endif if (!_switches[READ_ONLY]) fd = open(file, O_RDWR); if (fd < 0) { _switches[READ_ONLY]++; fd = open(file, O_RDONLY); } if (fd < 0) goto error; if (fstat(fd, &fbuf)) goto error; size = (fbuf.st_size - off); sectors = size >> SECTOR_SHIFT; if (_switches[VERBOSE_ARG]) fprintf(stderr, "losetup: set loop size to %llukB " "(%llu sectors)\n", (long long unsigned) sectors >> 1, (long long unsigned) sectors);#ifdef HAVE_SYS_STATVFS_H if (fstatvfs(fd, &fsbuf)) goto error; /* FIXME Fragment size currently unused */ blksize = fsbuf.f_frsize;#endif close(fd); if (dm_snprintf(table, tlen, "%llu %llu loop %s %llu\n", 0ULL, (long long unsigned)sectors, file, off) < 0) return 0; if (_switches[VERBOSE_ARG] > 1) fprintf(stderr, "Table: %s\n", table); return 1;error: if (fd > -1) close(fd); return 0;}static int _process_losetup_switches(const char *base, int *argc, char ***argv){ static int ind; int c; int encrypt_loop = 0, delete = 0, find = 0, show_all = 0; char *device_name = NULL; char *loop_file = NULL; off_t offset = 0;#ifdef HAVE_GETOPTLONG static struct option long_options[] = { {0, 0, 0, 0} };#endif optarg = 0; optind = OPTIND_INIT; while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "ade:fo:v", long_options, NULL)) != -1 ) { if (c == ':' || c == '?') return 0; if (c == 'a') show_all++; if (c == 'd') delete++; if (c == 'e') encrypt_loop++; if (c == 'f') find++; if (c == 'o') offset = atoi(optarg); if (c == 'v') _switches[VERBOSE_ARG]++; } *argv += optind ; *argc -= optind ; if (encrypt_loop){ fprintf(stderr, "%s: Sorry, cryptoloop is not yet implemented " "in this version.\n", base); return 0; } if (show_all) { fprintf(stderr, "%s: Sorry, show all is not yet implemented " "in this version.\n", base); return 0; } if (find) { fprintf(stderr, "%s: Sorry, find is not yet implemented " "in this version.\n", base); if (!*argc) return 0; } if (!*argc) { fprintf(stderr, "%s: Please specify loop_device.\n", base); _losetup_usage(stderr); return 0; } if (!(device_name = parse_loop_device_name((*argv)[0]))) { fprintf(stderr, "%s: Could not parse loop_device %s\n", base, (*argv)[0]); _losetup_usage(stderr); return 0; } if (delete) { *argc = 2; (*argv)[1] = device_name; (*argv)[0] = (char *) "remove"; return 1; } if (*argc != 2) { fprintf(stderr, "%s: Too few arguments\n", base); _losetup_usage(stderr); dm_free(device_name); return 0; } /* FIXME move these to make them available to native dmsetup */ if (!(loop_file = _get_abspath((*argv)[(find) ? 0 : 1]))) { fprintf(stderr, "%s: Could not parse loop file name %s\n", base, (*argv)[1]); _losetup_usage(stderr); dm_free(device_name); return 0; } /* FIXME Missing free */ _table = dm_malloc(LOOP_TABLE_SIZE); if (!_loop_table(_table, (size_t) LOOP_TABLE_SIZE, loop_file, device_name, offset)) { fprintf(stderr, "Could not build device-mapper table for %s\n", (*argv)[0]); dm_free(device_name); return 0; } _switches[TABLE_ARG]++; (*argv)[0] = (char *) "create"; (*argv)[1] = device_name ; return 1;}static int _process_switches(int *argc, char ***argv){ char *base, *namebase; static int ind; int c, r;#ifdef HAVE_GETOPTLONG static struct option long_options[] = { {"readonly", 0, &ind, READ_ONLY}, {"columns", 0, &ind, COLS_ARG}, {"exec", 1, &ind, EXEC_ARG}, {"force", 0, &ind, FORCE_ARG}, {"gid", 1, &ind, GID_ARG}, {"major", 1, &ind, MAJOR_ARG}, {"minor", 1, &ind, MINOR_ARG}, {"mode", 1, &ind, MODE_ARG}, {"noflush", 0, &ind, NOFLUSH_ARG}, {"noheadings", 0, &ind, NOHEADINGS_ARG}, {"nolockfs", 0, &ind, NOLOCKFS_ARG}, {"noopencount", 0, &ind, NOOPENCOUNT_ARG}, {"notable", 0, &ind, NOTABLE_ARG}, {"options", 1, &ind, OPTIONS_ARG}, {"separator", 1, &ind, SEPARATOR_ARG}, {"showkeys", 0, &ind, SHOWKEYS_ARG}, {"sort", 1, &ind, SORT_ARG}, {"table", 1, &ind, TABLE_ARG}, {"target", 1, &ind, TARGET_ARG}, {"tree", 0, &ind, TREE_ARG}, {"uid", 1, &ind, UID_ARG}, {"uuid", 1, &ind, UUID_ARG}, {"unbuffered", 0, &ind, UNBUFFERED_ARG}, {"verbose", 1, &ind, VERBOSE_ARG}, {"version", 0, &ind, VERSION_ARG}, {0, 0, 0, 0} };#else struct option long_options;#endif /* * Zero all the index counts. */ memset(&_switches, 0, sizeof(_switches)); memset(&_int_args, 0, sizeof(_int_args)); namebase = strdup((*argv)[0]); base = basename(namebase); if (!strcmp(base, "devmap_name")) { free(namebase); _switches[COLS_ARG]++; _switches[NOHEADINGS_ARG]++; _switches[OPTIONS_ARG]++; _switches[MAJOR_ARG]++; _switches[MINOR_ARG]++; _string_args[OPTIONS_ARG] = (char *) "name"; if (*argc == 3) { _int_args[MAJOR_ARG] = atoi((*argv)[1]); _int_args[MINOR_ARG] = atoi((*argv)[2]); *argc -= 2; *argv += 2; } else if ((*argc == 2) && (2 == sscanf((*argv)[1], "%i:%i", &_int_args[MAJOR_ARG], &_int_args[MINOR_ARG]))) { *argc -= 1; *argv += 1; } else { fprintf(stderr, "Usage: devmap_name <major> <minor>\n"); return 0; } (*argv)[0] = (char *) "info"; return 1; } if (!strcmp(base, "losetup") || !strcmp(base, "dmlosetup")){ r = _process_losetup_switches(base, argc, argv); free(namebase); return r; } free(namebase); optarg = 0; optind = OPTIND_INIT; while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCfGj:m:Mno:O:ru:Uv", long_options, NULL)) != -1) { if (c == ':' || c == '?') return 0; if (c == 'c' || c == 'C' || ind == COLS_ARG) _switches[COLS_ARG]++; if (c == 'f' || ind == FORCE_ARG) _switches[FORCE_ARG]++; if (c == 'r' || ind == READ_ONLY) _switches[READ_ONLY]++; if (c == 'j' || ind == MAJOR_ARG) { _switches[MAJOR_ARG]++; _int_args[MAJOR_ARG] = atoi(optarg); } if (c == 'm' || ind == MINOR_ARG) { _switches[MINOR_ARG]++; _int_args[MINOR_ARG] = atoi(optarg); } if (c == 'n' || ind == NOTABLE_ARG) _switches[NOTABLE_ARG]++; if (c == 'o' || ind == OPTIONS_ARG) { _switches[OPTIONS_ARG]++; _string_args[OPTIONS_ARG] = optarg; } if (ind == SEPARATOR_ARG) { _switches[SEPARATOR_ARG]++; _string_args[SEPARATOR_ARG] = optarg; } if (c == 'O' || ind == SORT_ARG) { _switches[SORT_ARG]++; _string_args[SORT_ARG] = optarg; } if (c == 'v' || ind == VERBOSE_ARG) _switches[VERBOSE_ARG]++; if (c == 'u' || ind == UUID_ARG) { _switches[UUID_ARG]++; _uuid = optarg; } if (c == 'G' || ind == GID_ARG) { _switches[GID_ARG]++; _int_args[GID_ARG] = atoi(optarg); } if (c == 'U' || ind == UID_ARG) { _switches[UID_ARG]++; _int_args[UID_ARG] = atoi(optarg); } if (c == 'M' || ind == MODE_ARG) { _switches[MODE_ARG]++; /* FIXME Accept modes as per chmod */ _int_args[MODE_ARG] = (int) strtol(optarg, NULL, 8); } if ((ind == EXEC_ARG)) { _switches[EXEC_ARG]++; _command = optarg; } if ((ind == TARGET_ARG)) { _switches[TARGET_ARG]++; _target = optarg; } if ((ind == NOFLUSH_ARG)) _switches[NOFLUSH_ARG]++; if ((ind == NOHEADINGS_ARG)) _switches[NOHEADINGS_ARG]++; if ((ind == NOLOCKFS_ARG)) _switches[NOLOCKFS_ARG]++; if ((ind == NOOPENCOUNT_ARG)) _switches[NOOPENCOUNT_ARG]++; if ((ind == SHOWKEYS_ARG)) _switches[SHOWKEYS_ARG]++; if ((ind == TABLE_ARG)) { _switches[TABLE_ARG]++; _table = optarg; } if ((ind == TREE_ARG)) _switches[TREE_ARG]++; if ((ind == UNBUFFERED_ARG)) _switches[UNBUFFERED_ARG]++; if ((ind == VERSION_ARG)) _switches[VERSION_ARG]++; } if (_switches[VERBOSE_ARG] > 1) dm_log_init_verbose(_switches[VERBOSE_ARG] - 1); if ((_switches[MAJOR_ARG] && !_switches[MINOR_ARG]) || (!_switches[MAJOR_ARG] && _switches[MINOR_ARG])) { fprintf(stderr, "Please specify both major number and " "minor number.\n"); return 0; } if (_switches[TREE_ARG] && !_process_tree_options(_string_args[OPTIONS_ARG])) return 0; if (_switches[TABLE_ARG] && _switches[NOTABLE_ARG]) { fprintf(stderr, "--table and --notable are incompatible.\n"); return 0; } *argv += optind; *argc -= optind; return 1;}int main(int argc, char **argv){ struct command *c; int r = 1; (void) setlocale(LC_ALL, ""); if (!_process_switches(&argc, &argv)) { fprintf(stderr, "Couldn't process command line.\n"); goto out; } if (_switches[VERSION_ARG]) { c = _find_command("version"); goto doit; } if (argc == 0) { _usage(stderr); goto out; } if (!(c = _find_command(argv[0]))) { fprintf(stderr, "Unknown command\n"); _usage(stderr); goto out; } if (argc < c->min_args + 1 || (c->max_args >= 0 && argc > c->max_args + 1)) { fprintf(stderr, "Incorrect number of arguments\n"); _usage(stderr); goto out; } if (_switches[COLS_ARG] && !_report_init(c)) goto out; doit: if (!c->fn(argc, argv, NULL)) { fprintf(stderr, "Command failed\n"); goto out; } r = 0;out: if (_report) { dm_report_output(_report); dm_report_free(_report); } if (_dtree) dm_tree_free(_dtree); return r;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -