Example #1
0
static int
do_mount(char *specialfile, char *dir, char *filesystemtype,
		 long flags, void *string_flags, int useMtab, int fakeIt,
		 char *mtab_opts, int mount_all)
{
	int status = 0;
#if defined BB_FEATURE_MOUNT_LOOP
	char *lofile = NULL;
#endif

	if (! fakeIt)
	{
#if defined BB_FEATURE_MOUNT_LOOP
		if (use_loop==TRUE) {
			int loro = flags & MS_RDONLY;
			
			lofile = specialfile;

			specialfile = find_unused_loop_device();
			if (specialfile == NULL) {
				error_msg_and_die("Could not find a spare loop device");
			}
			if (set_loop(specialfile, lofile, 0, &loro)) {
				error_msg_and_die("Could not setup loop device");
			}
			if (!(flags & MS_RDONLY) && loro) {	/* loop is ro, but wanted rw */
				error_msg("WARNING: loop device is read-only");
				flags |= MS_RDONLY;
			}
		}
#endif
		status = mount(specialfile, dir, filesystemtype, flags, string_flags);
		if (status < 0 && errno == EROFS) {
			error_msg("%s is write-protected, mounting read-only", specialfile);
			status = mount(specialfile, dir, filesystemtype, flags |= MS_RDONLY, string_flags);
		}
		/* Don't whine about already mounted filesystems when mounting all. */
		if (status < 0 && errno == EBUSY && mount_all)
			return TRUE;
	}


	/* If the mount was sucessful, do anything needed, then return TRUE */
	if (status == 0 || fakeIt==TRUE) {

#if defined BB_FEATURE_MTAB_SUPPORT
		if (useMtab) {
			erase_mtab(specialfile);	// Clean any stale entries
			write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts);
		}
#endif
		return (TRUE);
	}

	/* Bummer.  mount failed.  Clean up */
#if defined BB_FEATURE_MOUNT_LOOP
	if (lofile != NULL) {
		del_loop(specialfile);
	}
#endif

	if (errno == EPERM) {
		error_msg_and_die("permission denied. Are you root?");
	}

	return (FALSE);
}
Example #2
0
int do_mount (char *source, char *target, char *fstype, long flags, 
		int fakeIt, int mountall, int loop)
{
	int ret = 0;
	char *loopfile = NULL;

	if (source == NULL || target == NULL || fstype == NULL) { 
		printf("%s:%d: invalid settings.\n", __FUNCTION__, __LINE__);
		return 1;
	}

	if (!fakeIt) {
		if (loop) { 
			int loro = flags & MS_RDONLY;
			loopfile = strdup(source);
			source = find_unused_loop_device();
			if (!source) { 
				printf("Find spare loop device failed.\n");
				if (loopfile != NULL) { free(loopfile); loopfile = NULL;}
				return 1;
			} 
			if (set_loop(source, loopfile, 0, &loro)) { 
				if (loopfile != NULL) { free(loopfile); loopfile = NULL;}
				return 1;
			} 
			if (!(flags & MS_RDONLY) && !loro) { 
				flags |= MS_RDONLY;
			}
		}
		ret = mount(source, target, fstype, flags, NULL);
		if (ret < 0) {
			perror("Mount fail");
			fprintf(stderr, "%s:%d, mount %s on %s fail\n", __FUNCTION__, __LINE__, source, target);
		}
		if (ret < 0 && errno == EROFS) {
			printf("%s is write-protected, mounting read-only.\n", source);
			ret = mount(source, target, fstype, flags |= MS_RDONLY, NULL);
		}
		/* Don't whine about already mounted filesystems when mounting all. */
		if (ret < 0 && errno == EBUSY && mountall) {
			if (loopfile != NULL) { free(loopfile); loopfile = NULL;}
			return 0;
		}
	}

	if (ret == 0 || fakeIt == 1) {
		if (loop) {
			if (g_LoopData == NULL) {
				g_LoopData = malloc(sizeof(LOOP_DATA) * MAX_LOOP_DATA);
				if (g_LoopData) {
					memset(g_LoopData,0,sizeof(LOOP_DATA) * MAX_LOOP_DATA);
				}
			}
			if (g_LoopData) { // we need to save it for umount
				int k,loopfile_len;
				for (k=0;k<MAX_LOOP_DATA;k++) {
					if (g_LoopData[k].source == NULL) {
							g_LoopData[k].source = source; //we need to free it when we do umount
							g_LoopData[k].target = strdup(target);
							loopfile_len = strlen(loopfile) + 1;
							g_LoopData[k].orgfile = malloc(loopfile_len);
							strncpy(g_LoopData[k].orgfile,loopfile,loopfile_len);
							printf("save loop data(%d) source : %s target : %s\n",k,g_LoopData[k].source,g_LoopData[k].target);
						break;
					}
				}
			}
		}
		if (loopfile != NULL) { free(loopfile); loopfile = NULL;}
		return 0;
	}

	if (loopfile != NULL) { 
		del_loop(source);
		free(source);
		if (loopfile != NULL) { free(loopfile); loopfile = NULL;}
	}

	if (ret == EPERM) {
		printf("You don't have enough permission.\n");
	}

	return 1;
}
Example #3
0
int
main(int argc, char **argv){
	int fd, i, j, m, n, op, off, arg, c, d;
	struct slice all;
	struct pt *ptp;
	enum action what = LIST;
	char *type, *diskdevice, *device, *progname;
	int verbose = 0;
	char partname[PARTNAME_SIZE], params[PARTNAME_SIZE + 16];
	char * loopdev = NULL;
	char * delim = NULL;
	char *uuid = NULL;
	char *mapname = NULL;
	int loopro = 0;
	int hotplug = 0;
	int loopcreated = 0;
	int sync = 0;
	struct stat buf;
	uint32_t cookie = 0;

	initpts();
	init_crc32();

	type = device = diskdevice = NULL;
	memset(&all, 0, sizeof(all));
	memset(&partname, 0, sizeof(partname));

	/* Check whether hotplug mode. */
	progname = strrchr(argv[0], '/');

	if (!progname)
		progname = argv[0];
	else
		progname++;

	if (!strcmp(progname, "kpartx.dev")) { /* Hotplug mode */
		hotplug = 1;

		/* Setup for original kpartx variables */
		if (!(device = get_hotplug_device()))
			exit(1);

		diskdevice = device;
		what = ADD;
	} else if (argc < 2) {
		usage();
		exit(1);
	}

	while ((arg = getopt(argc, argv, short_opts)) != EOF) switch(arg) {
		case 'g':
			force_gpt=1;
			break;
		case 't':
			type = optarg;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'p':
			delim = optarg;
			break;
		case 'l':
			what = LIST;
			break;
		case 'a':
			what = ADD;
			break;
		case 'd':
			what = DELETE;
			break;
		case 's':
			sync = 1;
			break;
		default:
			usage();
			exit(1);
	}

	if (!sync)
		dm_udev_set_sync_support(0);

	if (dm_prereq(DM_TARGET, 0, 0, 0) && (what == ADD || what == DELETE)) {
		fprintf(stderr, "device mapper prerequisites not met\n");
		exit(1);
	}

	if (hotplug) {
		/* already got [disk]device */
	} else if (optind == argc-2) {
		device = argv[optind];
		diskdevice = argv[optind+1];
	} else if (optind == argc-1) {
		diskdevice = device = argv[optind];
	} else {
		usage();
		exit(1);
	}

	if (stat(device, &buf)) {
		printf("failed to stat() %s\n", device);
		exit (1);
	}

	if (S_ISREG (buf.st_mode)) {
		/* already looped file ? */
		loopdev = find_loop_by_file(device);

		if (!loopdev && what == DELETE)
			exit (0);

		if (!loopdev) {
			loopdev = find_unused_loop_device();

			if (set_loop(loopdev, device, 0, &loopro)) {
				fprintf(stderr, "can't set up loop\n");
				exit (1);
			}
			loopcreated = 1;
		}
		device = loopdev;
	}

	if (delim == NULL) {
		delim = malloc(DELIM_SIZE);
		memset(delim, 0, DELIM_SIZE);
		set_delimiter(device, delim);
	}

	off = find_devname_offset(device);

	if (!loopdev) {
		uuid = dm_mapuuid((unsigned int)MAJOR(buf.st_rdev),
				  (unsigned int)MINOR(buf.st_rdev));
		mapname = dm_mapname((unsigned int)MAJOR(buf.st_rdev),
				     (unsigned int)MINOR(buf.st_rdev));
	}

	if (!uuid)
		uuid = device + off;

	if (!mapname)
		mapname = device + off;

	fd = open(device, O_RDONLY);

	if (fd == -1) {
		perror(device);
		exit(1);
	}

	/* add/remove partitions to the kernel devmapper tables */
	int r = 0;
	for (i = 0; i < ptct; i++) {
		ptp = &pts[i];

		if (type && strcmp(type, ptp->type))
			continue;

		/* here we get partitions */
		n = ptp->fn(fd, all, slices, SIZE(slices));

#ifdef DEBUG
		if (n >= 0)
			printf("%s: %d slices\n", ptp->type, n);
#endif

		if (n > 0)
			close(fd);
		else
			continue;

		switch(what) {
		case LIST:
			for (j = 0, c = 0, m = 0; j < n; j++) {
				if (slices[j].size == 0)
					continue;
				if (slices[j].container > 0) {
					c++;
					continue;
				}

				slices[j].minor = m++;

				printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n",
				       mapname, delim, j+1,
				       slices[j].size, device,
				       slices[j].start);
			}
			/* Loop to resolve contained slices */
			d = c;
			while (c) {
				for (j = 0; j < n; j++) {
					uint64_t start;
					int k = slices[j].container - 1;

					if (slices[j].size == 0)
						continue;
					if (slices[j].minor > 0)
						continue;
					if (slices[j].container == 0)
						continue;
					slices[j].minor = m++;

					start = slices[j].start - slices[k].start;
					printf("%s%s%d : 0 %" PRIu64 " /dev/dm-%d %" PRIu64 "\n",
					       mapname, delim, j+1,
					       slices[j].size,
					       slices[k].minor, start);
					c--;
				}
				/* Terminate loop if nothing more to resolve */
				if (d == c)
					break;
			}

			if (loopcreated && S_ISREG (buf.st_mode)) {
				if (del_loop(device)) {
					if (verbose)
						printf("can't del loop : %s\n",
							device);
					exit(1);
				}
				printf("loop deleted : %s\n", device);
			}
			break;

		case DELETE:
			for (j = n-1; j >= 0; j--) {
				if (safe_sprintf(partname, "%s%s%d",
					     mapname, delim, j+1)) {
					fprintf(stderr, "partname too small\n");
					exit(1);
				}
				strip_slash(partname);

				if (!slices[j].size || !dm_map_present(partname))
					continue;

				if (!dm_simplecmd(DM_DEVICE_REMOVE, partname,
						  0, &cookie)) {
					r++;
					continue;
				}
				if (verbose)
					printf("del devmap : %s\n", partname);
			}

			if (S_ISREG (buf.st_mode)) {
				if (del_loop(device)) {
					if (verbose)
						printf("can't del loop : %s\n",
							device);
					exit(1);
				}
				printf("loop deleted : %s\n", device);
			}
			break;

		case ADD:
			for (j = 0, c = 0; j < n; j++) {
				if (slices[j].size == 0)
					continue;

				/* Skip all contained slices */
				if (slices[j].container > 0) {
					c++;
					continue;
				}

				if (safe_sprintf(partname, "%s%s%d",
					     mapname, delim, j+1)) {
					fprintf(stderr, "partname too small\n");
					exit(1);
				}
				strip_slash(partname);

				if (safe_sprintf(params, "%s %" PRIu64 ,
						 device, slices[j].start)) {
					fprintf(stderr, "params too small\n");
					exit(1);
				}

				op = (dm_map_present(partname) ?
					DM_DEVICE_RELOAD : DM_DEVICE_CREATE);

				if (!dm_addmap(op, partname, DM_TARGET, params,
					       slices[j].size, uuid, j+1,
					       buf.st_mode & 0777, buf.st_uid,
					       buf.st_gid, &cookie)) {
					fprintf(stderr, "create/reload failed on %s\n",
						partname);
					r++;
				}
				if (op == DM_DEVICE_RELOAD &&
				    !dm_simplecmd(DM_DEVICE_RESUME, partname,
						  1, &cookie)) {
					fprintf(stderr, "resume failed on %s\n",
						partname);
					r++;
				}
				dm_devn(partname, &slices[j].major,
					&slices[j].minor);

				if (verbose)
					printf("add map %s (%d:%d): 0 %" PRIu64 " %s %s\n",
					       partname, slices[j].major,
					       slices[j].minor, slices[j].size,
					       DM_TARGET, params);
			}
			/* Loop to resolve contained slices */
			d = c;
			while (c) {
				for (j = 0; j < n; j++) {
					uint64_t start;
					int k = slices[j].container - 1;

					if (slices[j].size == 0)
						continue;

					/* Skip all existing slices */
					if (slices[j].minor > 0)
						continue;

					/* Skip all simple slices */
					if (slices[j].container == 0)
						continue;

					/* Check container slice */
					if (slices[k].size == 0)
						fprintf(stderr, "Invalid slice %d\n",
							k);

					if (safe_sprintf(partname, "%s%s%d",
							 mapname, delim, j+1)) {
						fprintf(stderr, "partname too small\n");
						exit(1);
					}
					strip_slash(partname);

					start = slices[j].start - slices[k].start;
					if (safe_sprintf(params, "%d:%d %" PRIu64,
							 slices[k].major,
							 slices[k].minor,
							 start)) {
						fprintf(stderr, "params too small\n");
						exit(1);
					}

					op = (dm_map_present(partname) ?
					      DM_DEVICE_RELOAD : DM_DEVICE_CREATE);

					dm_addmap(op, partname, DM_TARGET, params,
						  slices[j].size, uuid, j+1,
						  buf.st_mode & 0777,
						  buf.st_uid, buf.st_gid,
						  &cookie);

					if (op == DM_DEVICE_RELOAD)
						dm_simplecmd(DM_DEVICE_RESUME,
							     partname, 1,
							     &cookie);

					dm_devn(partname, &slices[j].major,
						&slices[j].minor);

					if (verbose)
						printf("add map %s : 0 %" PRIu64 " %s %s\n",
						       partname, slices[j].size,
						       DM_TARGET, params);
					c--;
				}
				/* Terminate loop */
				if (d == c)
					break;
			}
			break;

		default:
			break;

		}
		if (n > 0)
			break;
	}
	dm_udev_wait(cookie);
	dm_lib_release();
	dm_lib_exit();

	return r;
}