return S_ISBLK(dev->stat.st_mode);
}
-static int open_dev(struct nvme_dev **devp, char *dev, int flags)
+static int open_dev(struct nvme_dev **devp, char *devstr, int flags)
{
- static struct nvme_dev _nvme_dev;
- static struct nvme_dev *nvme_dev = &_nvme_dev;
-
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
- /* Temporary: we use the global nvme_dev pointer for the nvme device.
- * This keeps the global in sync with the returned device. Later, we'll
- * remove the global entirely and allocate here instead.
- */
- *devp = nvme_dev;
+ dev = calloc(1, sizeof(*dev));
+ if (!dev)
+ return -1;
- nvme_dev->name = basename(dev);
- err = open(dev, flags);
- if (err < 0)
- goto perror;
- fd = err;
+ dev->name = basename(devstr);
+ err = open(devstr, flags);
+ if (err < 0) {
+ perror(devstr);
+ goto err_free;
+ }
+ dev->fd = err;
- err = fstat(fd, &nvme_dev->stat);
+ err = fstat(dev->fd, &dev->stat);
if (err < 0) {
- close(fd);
- goto perror;
+ perror(devstr);
+ goto err_close;
}
- if (!is_chardev(nvme_dev) && !is_blkdev(nvme_dev)) {
- fprintf(stderr, "%s is not a block or character device\n", dev);
- close(fd);
- return -ENODEV;
+ if (!is_chardev(dev) && !is_blkdev(dev)) {
+ fprintf(stderr, "%s is not a block or character device\n",
+ devstr);
+ err = -ENODEV;
+ goto err_close;
}
- nvme_dev->fd = fd;
+ *devp = dev;
return 0;
-perror:
- perror(dev);
+
+err_close:
+ close(dev->fd);
+err_free:
+ free(dev);
return err;
}
void dev_close(struct nvme_dev *dev)
{
close(dev->fd);
+ free(dev);
}
static int get_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)