⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmsetup.c

📁 Linux Device Mapper Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 + -