if (mpp->action != ACT_CREATE)
mpp->action = ACT_NOTHING;
}
+ dm_setgeometry(mpp);
return DOMAP_OK;
}
return DOMAP_FAIL;
dm_task_destroy(dmt);
return r;
}
+
+int dm_setgeometry(struct multipath *mpp)
+{
+ struct dm_task *dmt;
+ struct path *pp;
+ char heads[4], sectors[4];
+ char cylinders[10], start[32];
+ int r = 0;
+
+ if (!mpp)
+ return 1;
+
+ pp = first_path(mpp);
+ if (!pp) {
+ condlog(3, "%s: no path for geometry", mpp->alias);
+ return 1;
+ }
+ if (pp->geom.cylinders == 0 ||
+ pp->geom.heads == 0 ||
+ pp->geom.sectors == 0) {
+ condlog(3, "%s: invalid geometry on %s", mpp->alias, pp->dev);
+ return 1;
+ }
+
+ if (!(dmt = dm_task_create(DM_DEVICE_SET_GEOMETRY)))
+ return 0;
+
+ if (!dm_task_set_name(dmt, mpp->alias))
+ goto out;
+
+ dm_task_no_open_count(dmt);
+
+ /* What a sick interface ... */
+ snprintf(heads, 4, "%u", pp->geom.heads);
+ snprintf(sectors, 4, "%u", pp->geom.sectors);
+ snprintf(cylinders, 10, "%u", pp->geom.cylinders);
+ snprintf(start, 32, "%lu", pp->geom.start);
+ if (!dm_task_set_geometry(dmt, cylinders, heads, sectors, start)) {
+ condlog(3, "%s: Failed to set geometry", mpp->alias);
+ goto out;
+ }
+
+ r = dm_task_run(dmt);
+out:
+ dm_task_destroy(dmt);
+
+ return r;
+}
int dm_get_info (char * mapname, struct dm_info ** dmi);
int dm_rename (char * old, char * new);
char * dm_get_name(char * uuid);
+int dm_setgeometry(struct multipath *mpp);
#endif /* _DEVMAPPER_H */
return 0;
}
+static int
+get_geometry(struct path *pp)
+{
+ if (pp->fd < 0)
+ return 1;
+
+ if (ioctl(pp->fd, HDIO_GETGEO, &pp->geom)) {
+ condlog(2, "%s: HDIO_GETGEO failed with %d", pp->dev, errno);
+ memset(&pp->geom, 0, sizeof(pp->geom));
+ return 1;
+ }
+ condlog(3, "%s: %u cyl, %u heads, %u sectors/track, start at %lu",
+ pp->dev, pp->geom.cylinders, pp->geom.heads,
+ pp->geom.sectors, pp->geom.start);
+ return 0;
+}
+
static int
scsi_sysfs_pathinfo (struct path * pp, struct sysfs_device * parent)
{
goto blank;
}
+ if (mask & DI_SERIAL)
+ get_geometry(pp);
+
if (pp->bus == SYSFS_BUS_SCSI &&
scsi_ioctl_pathinfo(pp, mask))
goto blank;
char driver[NAME_SIZE]; /* device driver name */
};
+# ifndef HDIO_GETGEO
+# define HDIO_GETGEO 0x0301 /* get device geometry */
+
+struct hd_geometry {
+ unsigned char heads;
+ unsigned char sectors;
+ unsigned short cylinders;
+ unsigned long start;
+};
+#endif
struct path {
char dev[FILE_NAME_SIZE];
char dev_t[BLK_DEV_SIZE];
struct sysfs_device *sysdev;
struct scsi_idlun scsi_id;
struct sg_id sg_id;
+ struct hd_geometry geom;
char wwid[WWID_SIZE];
char vendor_id[SCSI_VENDOR_SIZE];
char product_id[SCSI_PRODUCT_SIZE];
struct checker checker;
struct multipath * mpp;
int fd;
-
+
/* configlet pointers */
struct hwentry * hwe;
};