From 495c2c6b6de9b307d2a90d3b33053685a77a3fad Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Tue, 5 Jun 2012 09:01:01 +0400 Subject: [PATCH] LU-1581 utils: move common funcs to mount_utils.c like functions to manipulate loop devices, etc Signed-off-by: Alex Zhuravlev Change-Id: I96c6347fbda130b81e7da267547af8a3a1c8b567 Reviewed-on: http://review.whamcloud.com/3217 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Li Wei Reviewed-by: Andreas Dilger --- lustre/utils/mkfs_lustre.c | 277 ------------------------------------- lustre/utils/mount_utils.c | 333 +++++++++++++++++++++++++++++++++++++-------- lustre/utils/mount_utils.h | 8 ++ 3 files changed, 287 insertions(+), 331 deletions(-) diff --git a/lustre/utils/mkfs_lustre.c b/lustre/utils/mkfs_lustre.c index c2d8d99..4236a4c 100644 --- a/lustre/utils/mkfs_lustre.c +++ b/lustre/utils/mkfs_lustre.c @@ -135,63 +135,6 @@ void usage(FILE *out) /*================ utility functions =====================*/ -char *strscat(char *dst, char *src, int buflen) { - dst[buflen - 1] = 0; - if (strlen(dst) + strlen(src) >= buflen) { - fprintf(stderr, "string buffer overflow (max %d): '%s' + '%s'" - "\n", buflen, dst, src); - exit(EOVERFLOW); - } - return strcat(dst, src); - -} - -char *strscpy(char *dst, char *src, int buflen) { - dst[0] = 0; - return strscat(dst, src, buflen); -} - -inline unsigned int -dev_major (unsigned long long int __dev) -{ - return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff); -} - -inline unsigned int -dev_minor (unsigned long long int __dev) -{ - return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); -} - -int get_os_version() -{ - static int version = 0; - - if (!version) { - int fd; - char release[4] = ""; - - fd = open("/proc/sys/kernel/osrelease", O_RDONLY); - if (fd < 0) { - fprintf(stderr, "%s: Warning: Can't resolve kernel " - "version, assuming 2.6\n", progname); - } else { - if (read(fd, release, 4) < 0) { - fprintf(stderr, "reading from /proc/sys/kernel" - "/osrelease: %s\n", strerror(errno)); - close(fd); - exit(-1); - } - close(fd); - } - if (strncmp(release, "2.4.", 4) == 0) - version = 24; - else - version = 26; - } - return version; -} - static int check_mtab_entry(char *spec) { FILE *fp; @@ -215,138 +158,6 @@ static int check_mtab_entry(char *spec) return(0); } -/*============ disk dev functions ===================*/ - -/* Setup a file in the first unused loop_device */ -int loop_setup(struct mkfs_opts *mop) -{ - char loop_base[20]; - char l_device[64]; - int i, ret = 0; - - /* Figure out the loop device names */ - if (!access("/dev/loop0", F_OK | R_OK)) { - strcpy(loop_base, "/dev/loop\0"); - } else if (!access("/dev/loop/0", F_OK | R_OK)) { - strcpy(loop_base, "/dev/loop/\0"); - } else { - fprintf(stderr, "%s: can't access loop devices\n", progname); - return EACCES; - } - - /* Find unused loop device */ - for (i = 0; i < MAX_LOOP_DEVICES; i++) { - char cmd[PATH_MAX]; - int cmdsz = sizeof(cmd); - - sprintf(l_device, "%s%d", loop_base, i); - if (access(l_device, F_OK | R_OK)) - break; - snprintf(cmd, cmdsz, "losetup %s > /dev/null 2>&1", l_device); - ret = system(cmd); - - /* losetup gets 1 (ret=256) for non-set-up device */ - if (ret) { - /* Set up a loopback device to our file */ - snprintf(cmd, cmdsz, "losetup %s %s", l_device, - mop->mo_device); - ret = run_command(cmd, cmdsz); - if (ret == 256) - /* someone else picked up this loop device - * behind our back */ - continue; - if (ret) { - fprintf(stderr, "%s: error %d on losetup: %s\n", - progname, ret, strerror(ret)); - return ret; - } - strscpy(mop->mo_loopdev, l_device, - sizeof(mop->mo_loopdev)); - return ret; - } - } - - fprintf(stderr, "%s: out of loop devices!\n", progname); - return EMFILE; -} - -int loop_cleanup(struct mkfs_opts *mop) -{ - char cmd[150]; - int ret = 1; - if ((mop->mo_flags & MO_IS_LOOP) && *mop->mo_loopdev) { - sprintf(cmd, "losetup -d %s", mop->mo_loopdev); - ret = run_command(cmd, sizeof(cmd)); - } - return ret; -} - -__u64 get_device_size(char* device) -{ - int ret, fd; - __u64 size = 0; - - fd = open(device, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "%s: cannot open %s: %s\n", - progname, device, strerror(errno)); - return 0; - } - -#ifdef BLKGETSIZE64 - /* size in bytes. bz5831 */ - ret = ioctl(fd, BLKGETSIZE64, (void*)&size); -#else - { - __u32 lsize = 0; - /* size in blocks */ - ret = ioctl(fd, BLKGETSIZE, (void*)&lsize); - size = (__u64)lsize * 512; - } -#endif - close(fd); - if (ret < 0) { - fprintf(stderr, "%s: size ioctl failed: %s\n", - progname, strerror(errno)); - return 0; - } - - vprint("device size = "LPU64"MB\n", size >> 20); - /* return value in KB */ - return size >> 10; -} - -int loop_format(struct mkfs_opts *mop) -{ - int fd; - - if (mop->mo_device_sz == 0) { - fatal(); - fprintf(stderr, "loop device requires a --device-size= " - "param\n"); - return EINVAL; - } - - fd = creat(mop->mo_device, S_IRUSR|S_IWUSR); - if (fd < 0) { - fatal(); - fprintf(stderr, "%s: Unable to create backing store: %s\n", - progname, strerror(errno)); - return errno; - } - - if (ftruncate(fd, mop->mo_device_sz * 1024) != 0) { - close(fd); - fatal(); - fprintf(stderr, "%s: Unable to truncate backing store: %s\n", - progname, strerror(errno)); - return errno; - } - - close(fd); - return 0; -} - /* ==================== Lustre config functions =============*/ void print_ldd(char *str, struct lustre_disk_data *ldd) @@ -400,24 +211,6 @@ static inline void badopt(const char *opt, char *type) usage(stderr); } -int add_param(char *buf, char *key, char *val) -{ - int end = sizeof(((struct lustre_disk_data *)0)->ldd_params); - int start = strlen(buf); - int keylen = 0; - - if (key) - keylen = strlen(key); - if (start + 1 + keylen + strlen(val) >= end) { - fprintf(stderr, "%s: params are too long-\n%s %s%s\n", - progname, buf, key ? key : "", val); - return 1; - } - - sprintf(buf + start, " %s%s", key ? key : "", val); - return 0; -} - /* from mount_lustre */ /* Get rid of symbolic hostnames for tcp, since kernel can't do lookups */ #define MAXNIDSTR 1024 @@ -725,76 +518,6 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, return 0; } -/* Search for opt in mntlist, returning true if found. - */ -static int in_mntlist(char *opt, char *mntlist) -{ - char *ml, *mlp, *item, *ctx = NULL; - - if (!(ml = strdup(mntlist))) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - mlp = ml; - while ((item = strtok_r(mlp, ",", &ctx))) { - if (!strcmp(opt, item)) - break; - mlp = NULL; - } - free(ml); - return (item != NULL); -} - -/* Issue a message on stderr for every item in wanted_mountopts that is not - * present in mountopts. The justwarn boolean toggles between error and - * warning message. Return an error count. - */ -static int check_mountfsoptions(char *mountopts, char *wanted_mountopts, - int justwarn) -{ - char *ml, *mlp, *item, *ctx = NULL; - int errors = 0; - - if (!(ml = strdup(wanted_mountopts))) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - mlp = ml; - while ((item = strtok_r(mlp, ",", &ctx))) { - if (!in_mntlist(item, mountopts)) { - fprintf(stderr, "%s: %s mount option `%s' is missing\n", - progname, justwarn ? "Warning: default" - : "Error: mandatory", item); - errors++; - } - mlp = NULL; - } - free(ml); - return errors; -} - -/* Trim embedded white space, leading and trailing commas from string s. - */ -static void trim_mountfsoptions(char *s) -{ - char *p; - - for (p = s; *p; ) { - if (isspace(*p)) { - memmove(p, p + 1, strlen(p + 1) + 1); - continue; - } - p++; - } - - while (s[0] == ',') - memmove(&s[0], &s[1], strlen(&s[1]) + 1); - - p = s + strlen(s) - 1; - while (p >= s && *p == ',') - *p-- = '\0'; -} - int main(int argc, char *const argv[]) { struct mkfs_opts mop; diff --git a/lustre/utils/mount_utils.c b/lustre/utils/mount_utils.c index f89d5c5..edb07fe 100644 --- a/lustre/utils/mount_utils.c +++ b/lustre/utils/mount_utils.c @@ -45,6 +45,7 @@ #include #include #include +#include "mount_utils.h" extern char *progname; extern int verbose; @@ -99,65 +100,289 @@ int run_command(char *cmd, int cmdsz) return rc; } -int get_mountdata(char *dev, struct lustre_disk_data *mo_ldd) +int add_param(char *buf, char *key, char *val) { + int end = sizeof(((struct lustre_disk_data *)0)->ldd_params); + int start = strlen(buf); + int keylen = 0; - char tmpdir[] = "/tmp/lustre_tmp.XXXXXX"; - char cmd[256]; - char filepnm[128]; - FILE *filep; - int ret = 0; - int ret2 = 0; - int cmdsz = sizeof(cmd); - - /* Make a temporary directory to hold Lustre data files. */ - if (!mkdtemp(tmpdir)) { - verrprint("%s: Can't create temporary directory %s: %s\n", - progname, tmpdir, strerror(errno)); - return errno; - } + if (key) + keylen = strlen(key); + if (start + 1 + keylen + strlen(val) >= end) { + fprintf(stderr, "%s: params are too long-\n%s %s%s\n", + progname, buf, key ? key : "", val); + return 1; + } - snprintf(cmd, cmdsz, "%s -c -R 'dump /%s %s/mountdata' %s", - DEBUGFS, MOUNT_DATA_FILE, tmpdir, dev); + sprintf(buf + start, " %s%s", key ? key : "", val); + return 0; +} - ret = run_command(cmd, cmdsz); - if (ret) { - verrprint("%s: Unable to dump %s dir (%d)\n", - progname, MOUNT_CONFIGS_DIR, ret); - goto out_rmdir; - } +int get_param(char *buf, char *key, char **val) +{ + int i, key_len = strlen(key); + char *ptr; - sprintf(filepnm, "%s/mountdata", tmpdir); - filep = fopen(filepnm, "r"); - if (filep) { - size_t num_read; - vprint("Reading %s\n", MOUNT_DATA_FILE); - num_read = fread(mo_ldd, sizeof(*mo_ldd), 1, filep); - if (num_read < 1 && ferror(filep)) { - fprintf(stderr, "%s: Unable to read from file (%s): %s\n", - progname, filepnm, strerror(errno)); - goto out_close; - } - } else { - verrprint("%s: Unable to read %d.%d config %s.\n", - progname, LUSTRE_MAJOR, LUSTRE_MINOR, filepnm); - ret = 1; - goto out_rmdir; - } + ptr = strstr(buf, key); + if (ptr) { + *val = strdup(ptr + key_len); + if (*val == NULL) + return ENOMEM; -out_close: - fclose(filep); - -out_rmdir: - snprintf(cmd, cmdsz, "rm -rf %s", tmpdir); - ret2 = run_command(cmd, cmdsz); - if (ret2) { - verrprint("Failed to remove temp dir %s (%d)\n", tmpdir, ret2); - /* failure return from run_command() is more important - * than the failure to remove a dir */ - if (!ret) - ret = ret2; - } + for (i = 0; i < strlen(*val); i++) + if (((*val)[i] == ' ') || ((*val)[i] == '\0')) + break; + + (*val)[i] = '\0'; + return 0; + } + + return ENOENT; +} + +char *strscat(char *dst, char *src, int buflen) +{ + dst[buflen - 1] = 0; + if (strlen(dst) + strlen(src) >= buflen) { + fprintf(stderr, "string buffer overflow (max %d): '%s' + '%s'" + "\n", buflen, dst, src); + exit(EOVERFLOW); + } + return strcat(dst, src); +} + +char *strscpy(char *dst, char *src, int buflen) +{ + dst[0] = 0; + return strscat(dst, src, buflen); +} + +static int in_mntlist(char *opt, char *mntlist) +{ + char *ml, *mlp, *item, *ctx = NULL; + + if (!(ml = strdup(mntlist))) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + mlp = ml; + while ((item = strtok_r(mlp, ",", &ctx))) { + if (!strcmp(opt, item)) + break; + mlp = NULL; + } + free(ml); + return (item != NULL); +} + +/* Issue a message on stderr for every item in wanted_mountopts that is not + * present in mountopts. The justwarn boolean toggles between error and + * warning message. Return an error count. + */ +int check_mountfsoptions(char *mountopts, char *wanted_mountopts, + int justwarn) +{ + char *ml, *mlp, *item, *ctx = NULL; + int errors = 0; + + if (!(ml = strdup(wanted_mountopts))) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + mlp = ml; + while ((item = strtok_r(mlp, ",", &ctx))) { + if (!in_mntlist(item, mountopts)) { + fprintf(stderr, "%s: %s mount option `%s' is missing\n", + progname, justwarn ? "Warning: default" + : "Error: mandatory", item); + errors++; + } + mlp = NULL; + } + free(ml); + return errors; +} + +/* Trim embedded white space, leading and trailing commas from string s. + */ +void trim_mountfsoptions(char *s) +{ + char *p; + + for (p = s; *p; ) { + if (isspace(*p)) { + memmove(p, p + 1, strlen(p + 1) + 1); + continue; + } + p++; + } + + while (s[0] == ',') + memmove(&s[0], &s[1], strlen(&s[1]) + 1); + + p = s + strlen(s) - 1; + while (p >= s && *p == ',') + *p-- = '\0'; +} + +/* Setup a file in the first unused loop_device */ +int loop_setup(struct mkfs_opts *mop) +{ + char loop_base[20]; + char l_device[64]; + int i, ret = 0; + + /* Figure out the loop device names */ + if (!access("/dev/loop0", F_OK | R_OK)) { + strcpy(loop_base, "/dev/loop\0"); + } else if (!access("/dev/loop/0", F_OK | R_OK)) { + strcpy(loop_base, "/dev/loop/\0"); + } else { + fprintf(stderr, "%s: can't access loop devices\n", progname); + return EACCES; + } + + /* Find unused loop device */ + for (i = 0; i < MAX_LOOP_DEVICES; i++) { + char cmd[PATH_MAX]; + int cmdsz = sizeof(cmd); + + sprintf(l_device, "%s%d", loop_base, i); + if (access(l_device, F_OK | R_OK)) + break; + snprintf(cmd, cmdsz, "losetup %s > /dev/null 2>&1", l_device); + ret = system(cmd); + + /* losetup gets 1 (ret=256) for non-set-up device */ + if (ret) { + /* Set up a loopback device to our file */ + snprintf(cmd, cmdsz, "losetup %s %s", l_device, + mop->mo_device); + ret = run_command(cmd, cmdsz); + if (ret == 256) + /* someone else picked up this loop device + * behind our back */ + continue; + if (ret) { + fprintf(stderr, "%s: error %d on losetup: %s\n", + progname, ret, strerror(ret)); + return ret; + } + strscpy(mop->mo_loopdev, l_device, + sizeof(mop->mo_loopdev)); + return ret; + } + } + + fprintf(stderr, "%s: out of loop devices!\n", progname); + return EMFILE; +} + +int loop_cleanup(struct mkfs_opts *mop) +{ + char cmd[150]; + int ret = 1; + if ((mop->mo_flags & MO_IS_LOOP) && *mop->mo_loopdev) { + sprintf(cmd, "losetup -d %s", mop->mo_loopdev); + ret = run_command(cmd, sizeof(cmd)); + } + return ret; +} + +int loop_format(struct mkfs_opts *mop) +{ + int fd; + + if (mop->mo_device_sz == 0) { + fatal(); + fprintf(stderr, "loop device requires a --device-size= " + "param\n"); + return EINVAL; + } + + fd = creat(mop->mo_device, S_IRUSR|S_IWUSR); + if (fd < 0) { + fatal(); + fprintf(stderr, "%s: Unable to create backing store: %s\n", + progname, strerror(errno)); + return errno; + } + + if (ftruncate(fd, mop->mo_device_sz * 1024) != 0) { + close(fd); + fatal(); + fprintf(stderr, "%s: Unable to truncate backing store: %s\n", + progname, strerror(errno)); + return errno; + } + + close(fd); + return 0; +} + +__u64 get_device_size(char* device) +{ + int ret, fd; + __u64 size = 0; + + fd = open(device, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: cannot open %s: %s\n", + progname, device, strerror(errno)); + return 0; + } + +#ifdef BLKGETSIZE64 + /* size in bytes. bz5831 */ + ret = ioctl(fd, BLKGETSIZE64, (void*)&size); +#else + { + __u32 lsize = 0; + /* size in blocks */ + ret = ioctl(fd, BLKGETSIZE, (void*)&lsize); + size = (__u64)lsize * 512; + } +#endif + close(fd); + if (ret < 0) { + fprintf(stderr, "%s: size ioctl failed: %s\n", + progname, strerror(errno)); + return 0; + } + + vprint("device size = "LPU64"MB\n", size >> 20); + /* return value in KB */ + return size >> 10; +} + +int file_create(char *path, int size) +{ + int ret; + int fd; + + ret = access(path, F_OK); + if (ret == 0) { + ret = unlink(path); + if (ret != 0) + return errno; + } + + fd = creat(path, S_IRUSR|S_IWUSR); + if (fd < 0) { + fatal(); + fprintf(stderr, "%s: Unable to create backing store: %s\n", + progname, strerror(errno)); + return errno; + } + + ret = ftruncate(fd, size * 1024); + close(fd); + if (ret != 0) { + fatal(); + fprintf(stderr, "%s: Unable to truncate backing store: %s\n", + progname, strerror(errno)); + return errno; + } - return ret; + return 0; } diff --git a/lustre/utils/mount_utils.h b/lustre/utils/mount_utils.h index 7a4433f..671de7e 100644 --- a/lustre/utils/mount_utils.h +++ b/lustre/utils/mount_utils.h @@ -77,6 +77,8 @@ int add_param(char *buf, char *key, char *val); int get_param(char *buf, char *key, char **val); char *strscat(char *dst, char *src, int buflen); char *strscpy(char *dst, char *src, int buflen); +int check_mountfsoptions(char *mountopts, char *wanted_mountopts, int justwarn); +void trim_mountfsoptions(char *s); __u64 get_device_size(char* device); int is_block(char *devname); @@ -86,4 +88,10 @@ int write_local_files(struct mkfs_opts *mop); int read_local_files(struct mkfs_opts *mop); int is_lustre_target(struct mkfs_opts *mop); +/* loopback helper functions */ +int file_create(char *path, int size); +int loop_format(struct mkfs_opts *mop); +int loop_setup(struct mkfs_opts *mop); +int loop_cleanup(struct mkfs_opts *mop); + #endif -- 1.8.3.1