diff options
author | NeilBrown <neilb@suse.de> | 2009-12-30 13:46:52 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2009-12-30 13:46:52 +1100 |
commit | 8409bc51e828bdf748138882e89229d6f6080b7c (patch) | |
tree | ac4cc8b3b7982a06db6f3ea9005f3c300b1abf8b | |
parent | c1e3ab8c1e76f4ae71ab23bcf5e8c2bf8bd3774e (diff) | |
parent | dd9bb2fbed335f69225ea1a3514bd27422288a18 (diff) | |
download | mdadm-8409bc51e828bdf748138882e89229d6f6080b7c.tar.gz mdadm-8409bc51e828bdf748138882e89229d6f6080b7c.tar.xz mdadm-8409bc51e828bdf748138882e89229d6f6080b7c.zip |
Merge branch 'klockwork' of git://github.com/djbw/mdadm
Conflicts:
super-intel.c
-rw-r--r-- | mdadm.h | 7 | ||||
-rw-r--r-- | platform-intel.c | 10 | ||||
-rw-r--r-- | probe_roms.c | 8 | ||||
-rw-r--r-- | super-intel.c | 80 | ||||
-rw-r--r-- | sysfs.c | 13 |
5 files changed, 69 insertions, 49 deletions
@@ -1023,3 +1023,10 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { #define ALGORITHM_PARITY_0_6 20 #define ALGORITHM_PARITY_N_6 ALGORITHM_PARITY_N +/* Define PATH_MAX in case we don't use glibc or standard library does + * not have PATH_MAX defined. Assume max path length is 4K characters. + */ +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + diff --git a/platform-intel.c b/platform-intel.c index d568ca6..30f7914 100644 --- a/platform-intel.c +++ b/platform-intel.c @@ -44,7 +44,7 @@ void free_sys_dev(struct sys_dev **list) struct sys_dev *find_driver_devices(const char *bus, const char *driver) { /* search sysfs for devices driven by 'driver' */ - char path[256]; + char path[292]; char link[256]; char *c; DIR *driver_dir; @@ -57,13 +57,17 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) if (!driver_dir) return NULL; for (de = readdir(driver_dir); de; de = readdir(driver_dir)) { + int n; + /* is 'de' a device? check that the 'subsystem' link exists and * that its target matches 'bus' */ sprintf(path, "/sys/bus/%s/drivers/%s/%s/subsystem", bus, driver, de->d_name); - if (readlink(path, link, sizeof(link)) < 0) + n = readlink(path, link, sizeof(link)); + if (n < 0 || n >= sizeof(link)) continue; + link[n] = '\0'; c = strrchr(link, '/'); if (!c) continue; @@ -202,7 +206,7 @@ const struct imsm_orom *find_imsm_orom(void) char *devt_to_devpath(dev_t dev) { - char device[40]; + char device[46]; sprintf(device, "/sys/dev/block/%d:%d/device", major(dev), minor(dev)); return canonicalize_file_name(device); diff --git a/probe_roms.c b/probe_roms.c index a9a8638..0f0ffbc 100644 --- a/probe_roms.c +++ b/probe_roms.c @@ -80,7 +80,7 @@ void probe_roms_exit(void) int probe_roms_init(unsigned long align) { - int fd; + int fd = -1; int rc = 0; /* valid values are 2048 and 512. 512 is for PCI-3.0 compliant @@ -107,9 +107,11 @@ int probe_roms_init(unsigned long align) if (rc == 0) rom_fd = fd; - else + else { + if (fd >= 0) + close(fd); probe_roms_exit(); - + } return rc; } diff --git a/super-intel.c b/super-intel.c index 609aaf5..d6951cc 100644 --- a/super-intel.c +++ b/super-intel.c @@ -318,6 +318,8 @@ static struct supertype *match_metadata_desc_imsm(char *arg) return NULL; st = malloc(sizeof(*st)); + if (!st) + return NULL; memset(st, 0, sizeof(*st)); st->ss = &super_imsm; st->max_devs = IMSM_MAX_DEVICES; @@ -708,7 +710,7 @@ static void print_imsm_disk(struct imsm_super *mpb, int index, __u32 reserved) char str[MAX_RAID_SERIAL_LEN + 1]; __u64 sz; - if (index < 0) + if (index < 0 || !disk) return; printf("\n"); @@ -966,6 +968,12 @@ static int imsm_enumerate_ports(const char *hba_path, int port_count, int host_b /* chop device path to 'host%d' and calculate the port number */ c = strchr(&path[hba_len], '/'); + if (!c) { + if (verbose) + fprintf(stderr, Name ": %s - invalid path name\n", path + hba_len); + err = 2; + break; + } *c = '\0'; if (sscanf(&path[hba_len], "host%d", &port) == 1) port -= host_base; @@ -1416,6 +1424,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info) struct imsm_dev *dev = get_imsm_dev(super, super->current_vol); struct imsm_map *map = get_imsm_map(dev, 0); struct dl *dl; + char *devname; for (dl = super->disks; dl; dl = dl->next) if (dl->raiddisk == info->disk.raid_disk) @@ -1478,9 +1487,11 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info) info->array.major_version = -1; info->array.minor_version = -2; - sprintf(info->text_version, "/%s/%d", - devnum2devname(st->container_dev), - info->container_member); + devname = devnum2devname(st->container_dev); + *info->text_version = '\0'; + if (devname) + sprintf(info->text_version, "/%s/%d", devname, info->container_member); + free(devname); info->safe_mode_delay = 4000; /* 4 secs like the Matrix driver */ uuid_from_super_imsm(st, info->uuid); } @@ -1779,7 +1790,7 @@ static void fd2devname(int fd, char *name) { struct stat st; char path[256]; - char dname[100]; + char dname[PATH_MAX]; char *nm; int rv; @@ -2689,13 +2700,14 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp, if (sra->array.major_version != -1 || sra->array.minor_version != -2 || - strcmp(sra->text_version, "imsm") != 0) - return 1; - + strcmp(sra->text_version, "imsm") != 0) { + err = 1; + goto error; + } /* load all mpbs */ for (sd = sra->devs, i = 0; sd; sd = sd->next, i++) { struct intel_super *s = alloc_super(0); - char nm[20]; + char nm[32]; int dfd; err = 1; @@ -2757,6 +2769,7 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp, super_list = super_list->next; free_imsm(s); } + sysfs_free(sra); if (err) return err; @@ -2999,6 +3012,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, map->ddf = 1; if (info->level == 1 && info->raid_disks > 2) { + free(dev); + free(dv); fprintf(stderr, Name": imsm does not support more than 2 disks" "in a raid1 volume\n"); return 0; @@ -3140,6 +3155,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, struct imsm_dev *_dev = __get_imsm_dev(mpb, 0); struct imsm_disk *_disk = __get_imsm_disk(mpb, dl->index); + if (!_dev || !_disk) { + fprintf(stderr, Name ": BUG mpb setup error\n"); + return 1; + } *_dev = *dev; *_disk = dl->disk; sum = random32(); @@ -3879,6 +3898,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, { int fd, cfd; struct mdinfo *sra; + int is_member = 0; /* if given unused devices create a container * if given given devices in a container create a member volume @@ -3916,21 +3936,6 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, dev, freesize, verbose); } - /* limit creation to the following levels */ - if (!dev) - switch (level) { - case 0: - case 1: - case 10: - case 5: - return 0; - default: - if (verbose) - fprintf(stderr, Name - ": IMSM only supports levels 0,1,5,10\n"); - return 1; - } - /* This device needs to be a device in an 'imsm' container */ fd = open(dev, O_RDONLY|O_EXCL, 0); if (fd >= 0) { @@ -3949,17 +3954,19 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, } /* Well, it is in use by someone, maybe an 'imsm' container. */ cfd = open_container(fd); + close(fd); if (cfd < 0) { - close(fd); if (verbose) fprintf(stderr, Name ": Cannot use %s: It is busy\n", dev); return 0; } sra = sysfs_read(cfd, 0, GET_VERSION); - close(fd); if (sra && sra->array.major_version == -1 && - strcmp(sra->text_version, "imsm") == 0) { + strcmp(sra->text_version, "imsm") == 0) + is_member = 1; + sysfs_free(sra); + if (is_member) { /* This is a member of a imsm container. Load the container * and try to create a volume */ @@ -3974,11 +3981,13 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, size, dev, freesize, verbose); } - close(cfd); - } else /* may belong to another container */ - return 0; + } - return 1; + if (verbose) + fprintf(stderr, Name ": failed container membership check\n"); + + close(cfd); + return 0; } #endif /* MDASSEMBLE */ @@ -4063,6 +4072,11 @@ static struct mdinfo *container_content_imsm(struct supertype *st) } this = malloc(sizeof(*this)); + if (!this) { + fprintf(stderr, Name ": failed to allocate %lu bytes\n", + sizeof(*this)); + break; + } memset(this, 0, sizeof(*this)); this->next = rest; @@ -4081,7 +4095,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st) ord = get_imsm_ord_tbl_ent(dev, slot); for (d = super->disks; d ; d = d->next) if (d->index == idx) - break; + break; recovery_start = MaxSector; if (d == NULL) @@ -4133,8 +4147,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st) info_d->events = __le32_to_cpu(mpb->generation_num); info_d->data_offset = __le32_to_cpu(map->pba_of_lba0); info_d->component_size = __le32_to_cpu(map->blocks_per_member); - if (d->devname) - strcpy(info_d->name, d->devname); } /* now that the disk list is up-to-date fixup recovery_start */ update_recovery_start(dev, this); @@ -100,13 +100,8 @@ void sysfs_init(struct mdinfo *mdi, int fd, int devnum) struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options) { - /* Longest possible name in sysfs, mounted at /sys, is - * /sys/block/md_dXXX/md/dev-XXXXX/block/dev - * /sys/block/md_dXXX/md/metadata_version - * which is about 41 characters. 50 should do for now - */ - char fname[50]; - char buf[1024]; + char fname[PATH_MAX]; + char buf[PATH_MAX]; char *base; char *dbase; struct mdinfo *sra; @@ -574,8 +569,8 @@ int sysfs_set_array(struct mdinfo *info, int vers) int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume) { - char dv[100]; - char nm[100]; + char dv[PATH_MAX]; + char nm[PATH_MAX]; char *dname; int rv; |