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); }
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); }