return converted;
}
-int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
+static int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
char **mountopts)
{
static struct option long_opt[] = {
"pool/dataset name not specified.\n");
return EINVAL;
} else {
- /* The device or pool/filesystem name */
- strscpy(mop->mo_device, argv[optind], sizeof(mop->mo_device));
-
/* Followed by optional vdevs */
if (optind < argc - 1)
mop->mo_pool_vdevs = (char **) &argv[optind + 1];
memset(&mop, 0, sizeof(mop));
set_defaults(&mop);
- /* device is last arg */
- strscpy(mop.mo_device, argv[argc - 1], sizeof(mop.mo_device));
+ /* Try to get the real path to the device */
+ ret = get_realpath(argv[argc - 1], &mop.mo_device);
+ if (ret != 0)
+ return ret;
ret = osd_init();
if (ret)
- return ret;
+ goto out;
#ifdef TUNEFS
/* For tunefs, we must read in the old values before parsing any
goto out;
}
- if (check_mtab_entry(mop.mo_device, mop.mo_device, NULL, NULL))
- return(EEXIST);
+ ret = check_mtab_entry(mop.mo_device, mop.mo_device, NULL, NULL);
+ if (ret != 0) {
+ fprintf(stderr, "%s: %s is already mounted\n",
+ progname, mop.mo_device);
+ goto out;
+ }
/* Create the loopback file */
if (mop.mo_flags & MO_IS_LOOP) {
out:
loop_cleanup(&mop);
+ free(mop.mo_device);
osd_fini();
/* Fix any crazy return values from system() */
memset(&mkop, 0, sizeof(mkop));
mkop.mo_ldd = *ldd;
mkop.mo_ldd.ldd_flags &= ~LDD_F_UPDATE;
- strcpy(mkop.mo_device, source);
+ mkop.mo_device = strdup(source);
ret = osd_prepare_lustre(&mkop,
default_mountopts, sizeof(default_mountopts),
{"verbose", 0, 0, 'v'},
{0, 0, 0, 0}
};
- char real_path[PATH_MAX] = {'\0'};
- FILE *f;
- char path[256], name[256];
- size_t sz;
char *ptr;
int opt, rc;
usage(stderr);
}
- mop->mo_usource = argv[optind];
- if (!mop->mo_usource) {
+ if (argv[optind] == NULL)
usage(stderr);
- }
- /**
- * Try to get the real path to the device, in case it is a
- * symbolic link for instance
- */
- if (realpath(mop->mo_usource, real_path) != NULL) {
- ptr = strrchr(real_path, '/');
- if (ptr && strncmp(ptr, "/dm-", 4) == 0 && isdigit(*(ptr + 4))) {
- snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptr+1);
- if ((f = fopen(path, "r"))) {
- /* read "<name>\n" from sysfs */
- if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
- name[sz - 1] = '\0';
- snprintf(real_path, sizeof(real_path), "/dev/mapper/%s", name);
- }
- fclose(f);
- }
- }
- mop->mo_usource = strdup(real_path);
- }
+ /* Try to get the real path to the device */
+ rc = get_realpath(argv[optind], &mop->mo_usource);
+ if (rc != 0)
+ mop->mo_usource = argv[optind];
ptr = strstr(mop->mo_usource, ":/");
if (ptr != NULL) {
#include <lustre_ver.h>
#include <sys/stat.h>
#include <sys/utsname.h>
+#include <linux/loop.h>
extern char *progname;
extern int verbose;
return strscat(dst, src, buflen);
}
+static int check_losetup(char *device, char *file_path)
+{
+ struct loop_info64 loop_info;
+ int fd;
+ int rc;
+
+ fd = open(device, O_RDONLY);
+ if (fd < 0)
+ return errno;
+
+ rc = ioctl(fd, LOOP_GET_STATUS64, (void *)&loop_info);
+ close(fd);
+ if (rc < 0)
+ return errno;
+
+ return strcmp(file_path, (char *)(loop_info.lo_file_name));
+}
+
int check_mtab_entry(char *spec1, char *spec2, char *mtpt, char *type)
{
FILE *fp;
struct mntent *mnt;
+ char lo_dev[] = "/dev/loop";
+ int lo_dev_len = strlen(lo_dev);
+ int ret = 0;
fp = setmntent(MOUNTED, "r");
if (fp == NULL)
return 0;
while ((mnt = getmntent(fp)) != NULL) {
- if ((strcmp(mnt->mnt_fsname, spec1) == 0 ||
- strcmp(mnt->mnt_fsname, spec2) == 0) &&
+ char *fsname = mnt->mnt_fsname;
+
+ if ((strcmp(fsname, spec1) == 0 ||
+ strcmp(fsname, spec2) == 0) &&
(mtpt == NULL || strcmp(mnt->mnt_dir, mtpt) == 0) &&
(type == NULL || strcmp(mnt->mnt_type, type) == 0)) {
- endmntent(fp);
- return(EEXIST);
+ ret = EEXIST;
+ break;
+ }
+ /* Check if the loop device is already mounted */
+ if (strncmp(fsname, lo_dev, lo_dev_len) != 0)
+ continue;
+ if (check_losetup(fsname, spec1) == 0 ||
+ check_losetup(fsname, spec2) == 0) {
+ ret = EEXIST;
+ break;
}
}
endmntent(fp);
- return 0;
+ return ret;
}
#define PROC_DIR "/proc/"
return 0;
}
+
+/**
+ * Try to get the real path to the device, in case it is a
+ * symbolic link or dm device for instance
+ */
+int get_realpath(char *path, char **device)
+{
+ FILE *f;
+ size_t sz;
+ char *ptr;
+ char name[256];
+ char real_path[PATH_MAX] = {'\0'};
+
+ if (realpath(path, real_path) == NULL)
+ return errno;
+
+ ptr = strrchr(real_path, '/');
+ if (ptr && strncmp(ptr, "/dm-", 4) == 0 && isdigit(*(ptr + 4))) {
+ snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptr+1);
+ f = fopen(path, "r");
+ if (f != NULL) {
+ /* read "<name>\n" from sysfs */
+ if (fgets(name, sizeof(name), f) != NULL) {
+ sz = strlen(name);
+ if (sz > 1) {
+ name[sz - 1] = '\0';
+ snprintf(real_path, sizeof(real_path),
+ "/dev/mapper/%s", name);
+ }
+ }
+ fclose(f);
+ }
+ }
+ *device = strdup(real_path);
+
+ return 0;
+}
/* used to describe the options to format the lustre disk, not persistent */
struct mkfs_opts {
struct lustre_disk_data mo_ldd; /* to be written in MOUNT_DATA_FILE */
- char mo_device[128]; /* disk device name */
+ char *mo_device; /* disk device name */
char **mo_pool_vdevs; /* list of pool vdevs */
char mo_loopdev[128]; /* in case a loop dev is needed */
char mo_mkfsopts[512]; /* options to the backing-store mkfs */
int flags, int freq, int pass);
int check_mountfsoptions(char *mountopts, char *wanted_mountopts, int justwarn);
void trim_mountfsoptions(char *s);
-__u64 get_device_size(char* device);
+__u64 get_device_size(char *device);
+int get_realpath(char *path, char **device);
int is_block(char *devname);
void disp_old_e2fsprogs_msg(const char *feature, int make_backfs);