X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=util.c;h=f818eabc6998b7316ab2f507ebe1625d3417d6d8;hp=ea30b3109096a3501ad41aa8e5ef9d8556ab49ea;hb=b83d95f362ff41e5ce63baa3bbcf0a76ea1f15aa;hpb=82b27616de634964db1a71bd5d9813db71e391a1 diff --git a/util.c b/util.c index ea30b310..f818eabc 100644 --- a/util.c +++ b/util.c @@ -1,7 +1,7 @@ /* - * mdctl - manage Linux "md" devices aka RAID arrays. + * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001 Neil Brown + * Copyright (C) 2001-2002 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -27,7 +27,7 @@ * Australia */ -#include "mdctl.h" +#include "mdadm.h" #include "md_p.h" #include @@ -113,6 +113,8 @@ int get_linux_version() int enough(int level, int raid_disks, int avail_disks) { switch (level) { + case -4: + return avail_disks>= 1; case -1: case 0: return avail_disks == raid_disks; @@ -197,8 +199,8 @@ int load_super(int fd, mdp_super_t *super) * 5 - no magic * 6 - wrong major version */ - long size; - long long offset; + unsigned long size; + unsigned long long offset; if (ioctl(fd, BLKGETSIZE, &size)) return 1; @@ -315,7 +317,7 @@ int check_raid(int fd, char *name) fprintf(stderr, Name ": %s appear to be part of a raid array:\n", name); crtime = super.ctime; - fprintf(stderr, " level=%d disks=%d ctime=%s", + fprintf(stderr, " level=%d devices=%d ctime=%s", super.level, super.raid_disks, ctime(&crtime)); return 1; } @@ -412,7 +414,7 @@ char *map_dev(int major, int minor) int calc_sb_csum(mdp_super_t *super) { unsigned int oldcsum = super->sb_csum; - unsigned long long newcsum = 0; /* FIXME why does this make it work?? */ + unsigned long long newcsum = 0; unsigned long csum; int i; unsigned int *superc = (int*) super; @@ -424,3 +426,88 @@ int calc_sb_csum(mdp_super_t *super) super->sb_csum = oldcsum; return csum; } + +char *human_size(long long bytes) +{ + static char buf[30]; + + + if (bytes < 5000*1024) + buf[0]=0; + else if (bytes < 2*1024LL*1024LL*1024LL) + sprintf(buf, " (%ld.%02ld MiB %ld.%02ld MB)", + (long)(bytes>>20), + (long)(bytes&0xfffff)/(0x100000/100), + (long)(bytes/1000/1000), + (long)((bytes%1000000)/10000) + ); + else + sprintf(buf, " (%ld.%02ld GiB %ld.%02ld GB)", + (long)(bytes>>30), + (long)((bytes>>10)&0xfffff)/(0x100000/100), + (long)(bytes/1000LL/1000LL/1000LL), + (long)(((bytes/1000)%1000000)/10000) + ); + return buf; +} + +char *human_size_brief(long long bytes) +{ + static char buf[30]; + + + if (bytes < 5000*1024) + sprintf(buf, "%ld.%02ldKiB", + (long)(bytes>>10), (long)((bytes&1023)*100/1024) + ); + else if (bytes < 2*1024LL*1024LL*1024LL) + sprintf(buf, "%ld.%02ldMiB", + (long)(bytes>>20), + (long)(bytes&0xfffff)/(0x100000/100) + ); + else + sprintf(buf, "%ld.%02ldGiB", + (long)(bytes>>30), + (long)((bytes>>10)&0xfffff)/(0x100000/100) + ); + return buf; +} + + +#define MD_MAJOR 9 +char *get_md_name(int dev) +{ + /* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */ + static char devname[50]; + struct stat stb; + dev_t rdev = MKDEV(MD_MAJOR, dev); + + sprintf(devname, "/dev/md%d", dev); + if (stat(devname, &stb) == 0 + && (S_IFMT&stb.st_mode) == S_IFBLK + && (stb.st_rdev == rdev)) + return devname; + + sprintf(devname, "/dev/md/%d", dev); + if (stat(devname, &stb) == 0 + && (S_IFMT&stb.st_mode) == S_IFBLK + && (stb.st_rdev == rdev)) + return devname; + + sprintf(devname, "/dev/.tmp.md%d", dev); + if (mknod(devname, S_IFBLK | 0600, rdev) == -1) + return NULL; + + if (stat(devname, &stb) == 0 + && (S_IFMT&stb.st_mode) == S_IFBLK + && (stb.st_rdev == rdev)) + return devname; + unlink(devname); + return NULL; +} + +void put_md_name(char *name) +{ + if (strncmp(name, "/dev/.tmp.md", 12)==0) + unlink(name); +}