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

📄 dmsetup.c

📁 Linux Device Mapper Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
static int _simple(int task, const char *name, uint32_t event_nr, int display){	int r = 0;	struct dm_task *dmt;	if (!(dmt = dm_task_create(task)))		return 0;	if (!_set_task_device(dmt, name, 0))		goto out;	if (event_nr && !dm_task_set_event_nr(dmt, event_nr))		goto out;	if (_switches[NOFLUSH_ARG] && !dm_task_no_flush(dmt))		goto out;	if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))		goto out;	if (_switches[NOLOCKFS_ARG] && !dm_task_skip_lockfs(dmt))		goto out;	r = dm_task_run(dmt);	if (r && display && _switches[VERBOSE_ARG])		r = _display_info(dmt);      out:	dm_task_destroy(dmt);	return r;}static int _suspend(int argc, char **argv, void *data __attribute((unused))){	return _simple(DM_DEVICE_SUSPEND, argc > 1 ? argv[1] : NULL, 0, 1);}static int _resume(int argc, char **argv, void *data __attribute((unused))){	return _simple(DM_DEVICE_RESUME, argc > 1 ? argv[1] : NULL, 0, 1);}static int _clear(int argc, char **argv, void *data __attribute((unused))){	return _simple(DM_DEVICE_CLEAR, argc > 1 ? argv[1] : NULL, 0, 1);}static int _wait(int argc, char **argv, void *data __attribute((unused))){	const char *name = NULL;	if (!_switches[UUID_ARG] && !_switches[MAJOR_ARG]) {		if (argc == 1) {			err("No device specified.");			return 0;		}		name = argv[1];		argc--, argv++;	}	return _simple(DM_DEVICE_WAITEVENT, name,		       (argc > 1) ? (uint32_t) atoi(argv[argc - 1]) : 0, 1);}static int _process_all(int argc, char **argv, int silent,			int (*fn) (int argc, char **argv, void *data)){	int r = 1;	struct dm_names *names;	unsigned next = 0;	struct dm_task *dmt;	if (!(dmt = dm_task_create(DM_DEVICE_LIST)))		return 0;	if (!dm_task_run(dmt)) {		r = 0;		goto out;	}	if (!(names = dm_task_get_names(dmt))) {		r = 0;		goto out;	}	if (!names->dev) {		if (!silent)			printf("No devices found\n");		goto out;	}	do {		names = (void *) names + next;		if (!fn(argc, argv, (void *) names))			r = 0;		next = names->next;	} while (next);      out:	dm_task_destroy(dmt);	return r;}static uint64_t _get_device_size(const char *name){	uint64_t start, length, size = UINT64_C(0);	struct dm_info info;	char *target_type, *params;	struct dm_task *dmt;	void *next = NULL;	if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))		return 0;	if (!_set_task_device(dmt, name, 0))		goto out;	if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))		goto out;	if (!dm_task_run(dmt))		goto out;	if (!dm_task_get_info(dmt, &info) || !info.exists)		goto out;	do {		next = dm_get_next_target(dmt, next, &start, &length,					  &target_type, &params);		size += length;	} while (next);      out:	dm_task_destroy(dmt);	return size;}static int _error_device(int argc __attribute((unused)), char **argv __attribute((unused)), void *data){	struct dm_names *names = (struct dm_names *) data;	struct dm_task *dmt;	const char *name;	uint64_t size;	int r = 0;	if (data)		name = names->name;	else		name = argv[1];	size = _get_device_size(name);	if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))		return 0;	if (!_set_task_device(dmt, name, 0))		goto error;	if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))		goto error;	if (_switches[READ_ONLY] && !dm_task_set_ro(dmt))		goto error;	if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))		goto error;	if (!dm_task_run(dmt))		goto error;	if (!_simple(DM_DEVICE_RESUME, name, 0, 0)) {		_simple(DM_DEVICE_CLEAR, name, 0, 0);		goto error;	}	r = 1;error:	dm_task_destroy(dmt);	return r;}static int _remove(int argc, char **argv, void *data __attribute((unused))){	int r;	if (_switches[FORCE_ARG] && argc > 1)		r = _error_device(argc, argv, NULL);	return _simple(DM_DEVICE_REMOVE, argc > 1 ? argv[1] : NULL, 0, 0);}static int _count_devices(int argc __attribute((unused)), char **argv __attribute((unused)), void *data __attribute((unused))){	_num_devices++;	return 1;}static int _remove_all(int argc __attribute((unused)), char **argv __attribute((unused)), void *data __attribute((unused))){	int r;	/* Remove all closed devices */	r =  _simple(DM_DEVICE_REMOVE_ALL, "", 0, 0) | dm_mknodes(NULL);	if (!_switches[FORCE_ARG])		return r;	_num_devices = 0;	r |= _process_all(argc, argv, 1, _count_devices);	/* No devices left? */	if (!_num_devices)		return r;	r |= _process_all(argc, argv, 1, _error_device);	r |= _simple(DM_DEVICE_REMOVE_ALL, "", 0, 0) | dm_mknodes(NULL);	_num_devices = 0;	r |= _process_all(argc, argv, 1, _count_devices);	if (!_num_devices)		return r;	fprintf(stderr, "Unable to remove %d device(s).\n", _num_devices);	return r;}static void _display_dev(struct dm_task *dmt, const char *name){	struct dm_info info;	if (dm_task_get_info(dmt, &info))		printf("%s\t(%u, %u)\n", name, info.major, info.minor);}static int _mknodes(int argc, char **argv, void *data __attribute((unused))){	return dm_mknodes(argc > 1 ? argv[1] : NULL);}static int _exec_command(const char *name){	int n;	static char path[PATH_MAX];	static char *args[ARGS_MAX + 1];	static int argc = 0;	char *c;	pid_t pid;	if (argc < 0)		return 0;	if (!dm_mknodes(name))		return 0;	n = snprintf(path, sizeof(path), "%s/%s", dm_dir(), name);	if (n < 0 || n > (int) sizeof(path) - 1)		return 0;	if (!argc) {		c = _command;		while (argc < ARGS_MAX) {			while (*c && isspace(*c))				c++;			if (!*c)				break;			args[argc++] = c;			while (*c && !isspace(*c))				c++;			if (*c)				*c++ = '\0';		}		if (!argc) {			argc = -1;			return 0;		}		if (argc == ARGS_MAX) {			err("Too many args to --exec\n");			argc = -1;			return 0;		}		args[argc++] = path;		args[argc] = NULL;	}	if (!(pid = fork())) {		execvp(args[0], args);		exit(127);	} else if (pid < (pid_t) 0)		return 0;	TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0));	return 1;}static int _status(int argc, char **argv, void *data){	int r = 0;	struct dm_task *dmt;	void *next = NULL;	uint64_t start, length;	char *target_type = NULL;	char *params, *c;	int cmd;	struct dm_names *names = (struct dm_names *) data;	const char *name = NULL;	int matched = 0;	int ls_only = 0;	struct dm_info info;	if (data)		name = names->name;	else {		if (argc == 1 && !_switches[UUID_ARG] && !_switches[MAJOR_ARG])			return _process_all(argc, argv, 0, _status);		if (argc == 2)			name = argv[1];	}	if (!strcmp(argv[0], "table"))		cmd = DM_DEVICE_TABLE;	else		cmd = DM_DEVICE_STATUS;	if (!strcmp(argv[0], "ls"))		ls_only = 1;	if (!(dmt = dm_task_create(cmd)))		return 0;	if (!_set_task_device(dmt, name, 0))		goto out;	if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))		goto out;	if (!dm_task_run(dmt))		goto out;	if (!dm_task_get_info(dmt, &info) || !info.exists)		goto out;	if (!name)		name = dm_task_get_name(dmt);	/* Fetch targets and print 'em */	do {		next = dm_get_next_target(dmt, next, &start, &length,					  &target_type, &params);		/* Skip if target type doesn't match */		if (_switches[TARGET_ARG] &&		    (!target_type || strcmp(target_type, _target)))			continue;		if (ls_only) {			if (!_switches[EXEC_ARG] || !_command ||			    _switches[VERBOSE_ARG])				_display_dev(dmt, name);			next = NULL;		} else if (!_switches[EXEC_ARG] || !_command ||			   _switches[VERBOSE_ARG]) {			if (!matched && _switches[VERBOSE_ARG])				_display_info(dmt);			if (data && !_switches[VERBOSE_ARG])				printf("%s: ", name);			if (target_type) {				/* Suppress encryption key */				if (!_switches[SHOWKEYS_ARG] &&				    cmd == DM_DEVICE_TABLE &&				    !strcmp(target_type, "crypt")) {					c = params;					while (*c && *c != ' ')						c++;					if (*c)						c++;					while (*c && *c != ' ')						*c++ = '0';				}				printf("%" PRIu64 " %" PRIu64 " %s %s",				       start, length, target_type, params);			}			printf("\n");		}		matched = 1;	} while (next);	if (data && _switches[VERBOSE_ARG] && matched && !ls_only)		printf("\n");	if (matched && _switches[EXEC_ARG] && _command && !_exec_command(name))		goto out;	r = 1;      out:	dm_task_destroy(dmt);	return r;}/* Show target names and their version numbers */static int _targets(int argc __attribute((unused)), char **argv __attribute((unused)), void *data __attribute((unused))){	int r = 0;	struct dm_task *dmt;	struct dm_versions *target;	struct dm_versions *last_target;	if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))		return 0;	if (!dm_task_run(dmt))		goto out;	target = dm_task_get_versions(dmt);	/* Fetch targets and print 'em */	do {		last_target = target;		printf("%-16s v%d.%d.%d\n", target->name, target->version[0],		       target->version[1], target->version[2]);		target = (void *) target + target->next;	} while (last_target != target);	r = 1;      out:	dm_task_destroy(dmt);	return r;}static int _info(int argc, char **argv, void *data){	int r = 0;	struct dm_task *dmt;	struct dm_names *names = (struct dm_names *) data;	char *name = NULL;	if (data)		name = names->name;	else {		if (argc == 1 && !_switches[UUID_ARG] && !_switches[MAJOR_ARG])			return _process_all(argc, argv, 0, _info);		if (argc == 2)			name = argv[1];	}	if (!(dmt = dm_task_create(DM_DEVICE_INFO)))		return 0;	if (!_set_task_device(dmt, name, 0))		goto out;	if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))		goto out;	if (!dm_task_run(dmt))		goto out;	r = _display_info(dmt);      out:	dm_task_destroy(dmt);	return r;}static int _deps(int argc, char **argv, void *data){	int r = 0;	uint32_t i;	struct dm_deps *deps;	struct dm_task *dmt;	struct dm_info info;	struct dm_names *names = (struct dm_names *) data;	char *name = NULL;	if (data)		name = names->name;	else {		if (argc == 1 && !_switches[UUID_ARG] && !_switches[MAJOR_ARG])			return _process_all(argc, argv, 0, _deps);		if (argc == 2)			name = argv[1];	}	if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))		return 0;	if (!_set_task_device(dmt, name, 0))		goto out;	if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))		goto out;	if (!dm_task_run(dmt))		goto out;	if (!dm_task_get_info(dmt, &info))		goto out;	if (!(deps = dm_task_get_deps(dmt)))		goto out;	if (!info.exists) {		printf("Device does not exist.\n");		r = 1;		goto out;	}	if (_switches[VERBOSE_ARG])		_display_info(dmt);	if (data && !_switches[VERBOSE_ARG])		printf("%s: ", name);	printf("%d dependencies\t:", deps->count);	for (i = 0; i < deps->count; i++)		printf(" (%d, %d)",		       (int) MAJOR(deps->device[i]),		       (int) MINOR(deps->device[i]));	printf("\n");	if (data && _switches[VERBOSE_ARG])		printf("\n");	r = 1;      out:	dm_task_destroy(dmt);	return r;}static int _display_name(int argc __attribute((unused)), char **argv __attribute((unused)), void *data){	struct dm_names *names = (struct dm_names *) data;	printf("%s\t(%d, %d)\n", names->name,	       (int) MAJOR(names->dev), (int) MINOR(names->dev));	return 1;}/* * Tree drawing code */enum {	TR_DEVICE=0,	/* display device major:minor number */	TR_TABLE,	TR_STATUS,	TR_ACTIVE,	TR_RW,	TR_OPENCOUNT,	TR_UUID,	TR_COMPACT,	TR_TRUNCATE,	TR_BOTTOMUP,	NUM_TREEMODE,};static int _tree_switches[NUM_TREEMODE];#define TR_PRINT_ATTRIBUTE ( _tree_switches[TR_ACTIVE] || \			     _tree_switches[TR_RW] || \			     _tree_switches[TR_OPENCOUNT] || \			     _tree_switches[TR_UUID] )#define TR_PRINT_TARGETS ( _tree_switches[TR_TABLE] || \			   _tree_switches[TR_STATUS] )/* Compact - fewer newlines */#define TR_PRINT_COMPACT (_tree_switches[TR_COMPACT] && \			  !TR_PRINT_ATTRIBUTE && \			  !TR_PRINT_TARGETS)/* FIXME Get rid of this */#define MAX_DEPTH 100/* Drawing character definition from pstree *//* [pstree comment] UTF-8 defines by Johan Myreen, updated by Ben Winslow */#define UTF_V	"\342\224\202"	/* U+2502, Vertical line drawing char */#define UTF_VR	"\342\224\234"	/* U+251C, Vertical and right */#define UTF_H	"\342\224\200"	/* U+2500, Horizontal */#define UTF_UR	"\342\224\224"	/* U+2514, Up and right */#define UTF_HD	"\342\224\254"	/* U+252C, Horizontal and down */#define VT_BEG	"\033(0\017"	/* use graphic chars */#define VT_END	"\033(B"	/* back to normal char set */#define VT_V	"x"		/* see UTF definitions above */#define VT_VR	"t"#define VT_H	"q"#define VT_UR	"m"#define VT_HD	"w"static struct {	const char *empty_2;	/*    */	const char *branch_2;	/* |- */	const char *vert_2;	/* |  */	const char *last_2;	/* `- */	const char *single_3;	/* --- */	const char *first_3;	/* -+- */}_tsym_ascii = {	"  ",	"|-",	"| ",	"`-",	"---",	"-+-"},_tsym_utf = {	"  ",	UTF_VR UTF_H,	UTF_V " ",	UTF_UR UTF_H,	UTF_H UTF_H UTF_H,	UTF_H UTF_HD UTF_H},_tsym_vt100 = {	"  ",	VT_BEG VT_VR VT_H VT_END,	VT_BEG VT_V VT_END " ",	VT_BEG VT_UR VT_H VT_END,	VT_BEG VT_H VT_H VT_H VT_END,	VT_BEG VT_H VT_HD VT_H VT_END},*_tsym = &_tsym_ascii;/* * Tree drawing functions. *//* FIXME Get rid of these statics - use dynamic struct *//* FIXME Explain what these vars are for */static int _tree_width[MAX_DEPTH], _tree_more[MAX_DEPTH];static int _termwidth = 80;	/* Maximum output width */static int _cur_x = 1;		/* Current horizontal output position */static char _last_char = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -