#include "device-handler.h"
#include "discover-server.h"
+#include "devmapper.h"
#include "user-event.h"
#include "platform.h"
#include "event.h"
} device_type_map[] = {
{ IPMI_BOOTDEV_NETWORK, DEVICE_TYPE_NETWORK },
{ IPMI_BOOTDEV_DISK, DEVICE_TYPE_DISK },
+ { IPMI_BOOTDEV_DISK, DEVICE_TYPE_USB },
{ IPMI_BOOTDEV_CDROM, DEVICE_TYPE_OPTICAL },
};
return "";
}
+static inline const char *get_device_path(struct discover_device *dev)
+{
+ return dev->ramdisk ? dev->ramdisk->snapshot : dev->device_path;
+}
+
static bool check_existing_mount(struct discover_device *dev)
{
struct stat devstat, mntstat;
+ const char *device_path;
struct mntent *mnt;
FILE *fp;
int rc;
- rc = stat(dev->device_path, &devstat);
+ device_path = get_device_path(dev);
+
+ rc = stat(device_path, &devstat);
if (rc) {
pb_debug("%s: stat failed: %s\n", __func__, strerror(errno));
return false;
static int mount_device(struct discover_device *dev)
{
- const char *fstype;
+ const char *fstype, *device_path;
int rc;
if (!dev->device_path)
goto err_free;
}
+ device_path = get_device_path(dev);
+
pb_log("mounting device %s read-only\n", dev->device_path);
errno = 0;
- rc = mount(dev->device_path, dev->mount_path, fstype,
+ rc = mount(device_path, dev->mount_path, fstype,
MS_RDONLY | MS_SILENT,
fs_parameters(MS_RDONLY, fstype));
if (!rc) {
}
pb_log("couldn't mount device %s: mount failed: %s\n",
- dev->device_path, strerror(errno));
+ device_path, strerror(errno));
+
+ /* If mount fails clean up any snapshot */
+ devmapper_destroy_snapshot(dev);
pb_rmdir_recursive(mount_base(), dev->mount_path);
err_free:
static int umount_device(struct discover_device *dev)
{
+ const char *device_path;
int rc;
if (!dev->mounted || !dev->unmount)
return 0;
- pb_log("unmounting device %s\n", dev->device_path);
+ device_path = get_device_path(dev);
+
+ pb_log("unmounting device %s\n", device_path);
rc = umount(dev->mount_path);
if (rc)
return -1;
dev->mounted = false;
+ devmapper_destroy_snapshot(dev);
pb_rmdir_recursive(mount_base(), dev->mount_path);
int device_request_write(struct discover_device *dev, bool *release)
{
- const char *fstype;
+ const char *fstype, *device_path;
+ const struct config *config;
int rc;
*release = false;
+ config = config_get();
+ if (!config->allow_writes)
+ return -1;
+
if (!dev->mounted)
return -1;
fstype = discover_device_get_param(dev, "ID_FS_TYPE");
- pb_log("remounting device %s read-write\n", dev->device_path);
+ device_path = get_device_path(dev);
+
+ pb_log("remounting device %s read-write\n", device_path);
rc = umount(dev->mount_path);
if (rc) {
- pb_log("Failed to unmount %s\n", dev->mount_path);
+ pb_log("Failed to unmount %s: %s\n",
+ dev->mount_path, strerror(errno));
return -1;
}
- rc = mount(dev->device_path, dev->mount_path, fstype,
+
+ rc = mount(device_path, dev->mount_path, fstype,
MS_SILENT,
fs_parameters(MS_REMOUNT, fstype));
if (rc)
return 0;
mount_ro:
- pb_log("Unable to remount device %s read-write\n", dev->device_path);
- rc = mount(dev->device_path, dev->mount_path, fstype,
+ pb_log("Unable to remount device %s read-write: %s\n",
+ device_path, strerror(errno));
+ if (mount(device_path, dev->mount_path, fstype,
MS_RDONLY | MS_SILENT,
- fs_parameters(MS_RDONLY, fstype));
- if (rc)
- pb_log("Unable to recover mount for %s\n", dev->device_path);
+ fs_parameters(MS_RDONLY, fstype)))
+ pb_log("Unable to recover mount for %s: %s\n",
+ device_path, strerror(errno));
return -1;
}
void device_release_write(struct discover_device *dev, bool release)
{
- const char *fstype;
+ const char *fstype, *device_path;
+ int rc = 0;
if (!release)
return;
+ device_path = get_device_path(dev);
+
fstype = discover_device_get_param(dev, "ID_FS_TYPE");
- pb_log("remounting device %s read-only\n", dev->device_path);
- mount(dev->device_path, dev->mount_path, "",
- MS_REMOUNT | MS_RDONLY | MS_SILENT,
+ pb_log("remounting device %s read-only\n", device_path);
+
+ if (umount(dev->mount_path)) {
+ pb_log("Failed to unmount %s\n", dev->mount_path);
+ return;
+ }
+ dev->mounted_rw = dev->mounted = false;
+
+ if (dev->ramdisk) {
+ devmapper_merge_snapshot(dev);
+ /* device_path becomes stale after merge */
+ device_path = get_device_path(dev);
+ }
+
+ mount(device_path, dev->mount_path, fstype,
+ MS_RDONLY | MS_SILENT,
fs_parameters(MS_RDONLY, fstype));
- dev->mounted_rw = false;
+ if (rc)
+ pb_log("Failed to remount %s read-only: %s\n",
+ device_path, strerror(errno));
+ else
+ dev->mounted = true;
}
#else