+ /* if given unused devices create a container
+ * if given given devices in a container create a member volume
+ */
+ if (level == LEVEL_CONTAINER) {
+ st->ss = &super_imsm_container;
+ if (dev) {
+ /* validate the container, dev == NULL */
+ int rv = st->ss->validate_geometry(st, level, layout,
+ raiddisks, chunk,
+ size,
+ NULL, freesize);
+ if (rv)
+ return rv;
+ }
+ return st->ss->validate_geometry(st, level, layout, raiddisks,
+ chunk, size, dev, freesize);
+ }
+
+ if (st->sb) {
+ /* creating in a given container */
+ st->ss = &super_imsm_volume;
+ if (dev) {
+ int rv = st->ss->validate_geometry(st, level, layout,
+ raiddisks, chunk,
+ size,
+ NULL, freesize);
+ if (rv)
+ return rv;
+ }
+ return st->ss->validate_geometry(st, level, layout, raiddisks,
+ chunk, size, dev, freesize);
+ }
+
+ /* limit creation to the following levels */
+ if (!dev)
+ switch (level) {
+ case 0:
+ case 1:
+ case 10:
+ case 5:
+ break;
+ default:
+ return 1;
+ }
+
+ /* This device needs to be a device in an 'imsm' container */
+ fd = open(dev, O_RDONLY|O_EXCL, 0);
+ if (fd >= 0) {
+ fprintf(stderr,
+ Name ": Cannot create this array on device %s\n",
+ dev);
+ close(fd);
+ return 0;
+ }
+ if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
+ fprintf(stderr, Name ": Cannot open %s: %s\n",
+ dev, strerror(errno));
+ return 0;
+ }
+ /* Well, it is in use by someone, maybe an 'imsm' container. */
+ cfd = open_container(fd);
+ if (cfd < 0) {
+ close(fd);
+ 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) {
+ /* This is a member of a imsm container. Load the container
+ * and try to create a volume
+ */
+ struct intel_super *super;
+ st->ss = &super_imsm_volume;
+ if (load_super_imsm_all(st, cfd, (void **) &super, NULL, 1) == 0) {
+ st->sb = super;
+ st->container_dev = fd2devnum(cfd);
+ close(cfd);
+ return st->ss->validate_geometry(st, level, layout,
+ raiddisks, chunk, size,
+ dev, freesize);
+ }
+ close(cfd);
+ } else /* may belong to another container */
+ return 0;
+
+ return 1;