예제 #1
0
void
hammer_cmd_pseudofs_create(char **av, int ac, int is_slave)
{
	struct hammer_ioc_pseudofs_rw pfs;
	struct hammer_pseudofs_data pfsd;
	struct stat st;
	const char *path;
	char *dirpath;
	char *linkpath;
	int pfs_id;
	int fd;
	int error;

	if (ac == 0)
		pseudofs_usage(1);
	path = av[0];
	if (lstat(path, &st) == 0) {
		fprintf(stderr, "Cannot create %s, file exists!\n", path);
		exit(1);
	}

	/*
	 * Figure out the directory prefix, taking care of degenerate
	 * cases.
	 */
	dirpath = strdup(path);
	if (strrchr(dirpath, '/') != NULL) {
		*strrchr(dirpath, '/') = 0;
		if (dirpath[0] == 0) {
			free(dirpath);
			dirpath = strdup("/");
		}
	} else {
		free(dirpath);
		dirpath = strdup(".");
	}
	fd = open(dirpath, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Cannot open directory %s\n", dirpath);
		exit(1);
	}

	error = 0;
	for (pfs_id = 0; pfs_id < HAMMER_MAX_PFS; ++pfs_id) {
		bzero(&pfs, sizeof(pfs));
		bzero(&pfsd, sizeof(pfsd));
		pfs.pfs_id = pfs_id;
		pfs.ondisk = &pfsd;
		pfs.bytes = sizeof(pfsd);
		pfs.version = HAMMER_IOC_PSEUDOFS_VERSION;
		if (ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs) < 0) {
			error = errno;
			break;
		}
	}
	if (pfs_id == HAMMER_MAX_PFS) {
		fprintf(stderr, "Cannot create %s, all PFSs in use\n", path);
		exit(1);
	}
	if (error != ENOENT) {
		fprintf(stderr, "Cannot create %s, got %s during scan\n",
			path, strerror(error));
		exit(1);
	}

	/*
	 * Create the new PFS
	 */
	printf("Creating PFS #%d\t", pfs_id);
	bzero(&pfsd, sizeof(pfsd));
	init_pfsd(&pfsd, is_slave);
	pfs.pfs_id = pfs_id;
	pfs.ondisk = &pfsd;
	pfs.bytes = sizeof(pfsd);
	pfs.version = HAMMER_IOC_PSEUDOFS_VERSION;

	if (ioctl(fd, HAMMERIOC_SET_PSEUDOFS, &pfs) < 0) {
		printf("failed: %s\n", strerror(errno));
	} else {
		/* special symlink, must be exactly 10 characters */
		asprintf(&linkpath, "@@PFS%05d", pfs_id);
		if (symlink(linkpath, path) < 0) {
			printf("failed: cannot create symlink: %s\n",
				strerror(errno));
		} else {
			printf("succeeded!\n");
			hammer_cmd_pseudofs_update(av, ac);
		}
	}
	close(fd);
}
예제 #2
0
void
hammer_cmd_pseudofs_create(char **av, int ac, int is_slave)
{
	struct hammer_ioc_pseudofs_rw pfs;
	struct hammer_pseudofs_data pfsd;
	struct stat st;
	const char *path;
	char *dirpath;
	char *linkpath;
	int pfs_id;
	int fd;
	int error;

	if (ac == 0)
		pseudofs_usage(1);
	path = av[0];
	if (lstat(path, &st) == 0) {
		fprintf(stderr, "Cannot create %s, file exists!\n", path);
		exit(1);
	}

	/*
	 * Figure out the directory prefix, taking care of degenerate
	 * cases.
	 */
	dirpath = getdir(path);
	fd = open(dirpath, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Cannot open directory %s\n", dirpath);
		exit(1);
	}

	/*
	 * Avoid foot-shooting.  Don't let the user create a PFS
	 * softlink via a PFS.  PFS softlinks may only be accessed
	 * via the master filesystem.  Checking it here ensures
	 * other PFS commands access PFS under the master filesystem.
	 */
	bzero(&pfs, sizeof(pfs));
	bzero(&pfsd, sizeof(pfsd));
	pfs.pfs_id = -1;
	pfs.ondisk = &pfsd;
	pfs.bytes = sizeof(pfsd);

	ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs);
	if (pfs.pfs_id != 0) {
		fprintf(stderr,
			"You are attempting to access a PFS softlink "
			"from a PFS.  It may not represent the PFS\n"
			"on the main filesystem mount that you "
			"expect!  You may only access PFS softlinks\n"
			"via the main filesystem mount!\n");
		exit(1);
	}

	error = 0;
	for (pfs_id = 0; pfs_id < HAMMER_MAX_PFS; ++pfs_id) {
		bzero(&pfs, sizeof(pfs));
		bzero(&pfsd, sizeof(pfsd));
		pfs.pfs_id = pfs_id;
		pfs.ondisk = &pfsd;
		pfs.bytes = sizeof(pfsd);
		pfs.version = HAMMER_IOC_PSEUDOFS_VERSION;
		if (ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs) < 0) {
			error = errno;
			break;
		}
	}
	if (pfs_id == HAMMER_MAX_PFS) {
		fprintf(stderr, "Cannot create %s, all PFSs in use\n", path);
		exit(1);
	}
	if (error != ENOENT) {
		fprintf(stderr, "Cannot create %s, got %s during scan\n",
			path, strerror(error));
		exit(1);
	}

	/*
	 * Create the new PFS
	 */
	printf("Creating PFS #%d\t", pfs_id);
	init_pfsd(&pfsd, is_slave);
	pfs.pfs_id = pfs_id;
	pfs.ondisk = &pfsd;
	pfs.bytes = sizeof(pfsd);
	pfs.version = HAMMER_IOC_PSEUDOFS_VERSION;

	if (ioctl(fd, HAMMERIOC_SET_PSEUDOFS, &pfs) < 0) {
		printf("failed: %s\n", strerror(errno));
	} else {
		/* special symlink, must be exactly 10 characters */
		asprintf(&linkpath, "@@PFS%05d", pfs_id);
		if (symlink(linkpath, path) < 0) {
			printf("failed: cannot create symlink: %s\n",
				strerror(errno));
		} else {
			printf("succeeded!\n");
			hammer_cmd_pseudofs_update(av, ac);
		}
	}
	free(dirpath);
	close(fd);
}