/* * Instructs the volume manager to enable or disable USB mass storage * on any volumes configured to use it. */ int volmgr_enable_ums(boolean enable) { volume_t *v = vol_root; while(v) { if (v->ums_path) { int rc; if (enable) { pthread_mutex_lock(&v->lock); if (v->state == volstate_mounted) volmgr_send_eject_request(v); else if (v->state == volstate_ums || v->state == volstate_nomedia) { pthread_mutex_unlock(&v->lock); goto next_vol; } // Stop the volume, and enable UMS in the callback rc = volmgr_shutdown_volume(v, _cb_volstopped_for_ums_enable, false); if (rc != -EINPROGRESS) { if (rc) LOGE("unable to shutdown volume '%s'", v->mount_point); pthread_mutex_unlock(&v->lock); } } else { // Disable UMS pthread_mutex_lock(&v->lock); if (v->state != volstate_ums) { pthread_mutex_unlock(&v->lock); goto next_vol; } if ((rc = ums_disable(v->ums_path)) < 0) { LOGE("unable to disable ums on '%s'", v->mount_point); pthread_mutex_unlock(&v->lock); continue; } LOG_VOL("Kick-starting volume %d:%d after UMS disable", v->dev->disk->major, v->dev->disk->minor); // Start volume if ((rc = _volmgr_consider_disk_and_vol(v, v->dev->disk)) < 0) { LOGE("volmgr failed to consider disk %d:%d", v->dev->disk->major, v->dev->disk->minor); } pthread_mutex_unlock(&v->lock); } } next_vol: v = v->next; } return 0; }
int volmgr_notify_eject(blkdev_t *dev, void (* cb) (blkdev_t *)) { LOG_VOL("Volmgr notified of %d:%d eject", dev->major, dev->minor); volume_t *v; int rc; // XXX: Partitioning support is going to need us to stop *all* // devices in this volume if (!(v = volmgr_lookup_volume_by_dev(dev))) { if (cb) cb(dev); return 0; } pthread_mutex_lock(&v->lock); volume_state_t old_state = v->state; if (v->state == volstate_mounted || v->state == volstate_ums || v->state == volstate_checking) { volume_setstate(v, volstate_badremoval); /* * Stop any devmapper volumes which * are using us as a source * XXX: We may need to enforce stricter * order here */ volume_t *dmvol = vol_root; while (dmvol) { if ((dmvol->media_type == media_devmapper) && (dmvol->dm->src_type == dmsrc_loopback) && (!strncmp(dmvol->dm->type_data.loop.loop_src, v->mount_point, strlen(v->mount_point)))) { pthread_mutex_lock(&dmvol->lock); if (dmvol->state != volstate_nomedia) { rc = volmgr_shutdown_volume(dmvol, _cb_volstopped_for_devmapper_teardown, false); if (rc != -EINPROGRESS) { if (rc) LOGE("unable to shutdown volume '%s'", v->mount_point); pthread_mutex_unlock(&dmvol->lock); } } else pthread_mutex_unlock(&dmvol->lock); } dmvol = dmvol->next; } } else if (v->state == volstate_formatting) { /* * The device is being ejected due to * kernel disk revalidation. */ LOG_VOL("Volmgr ignoring eject of %d:%d (volume formatting)", dev->major, dev->minor); if (cb) cb(dev); pthread_mutex_unlock(&v->lock); return 0; } else volume_setstate(v, volstate_nomedia); if (old_state == volstate_ums) { ums_disable(v->ums_path); pthread_mutex_unlock(&v->lock); } else { int rc = volmgr_stop_volume(v, _cb_volume_stopped_for_eject, cb, false); if (rc != -EINPROGRESS) { if (rc) LOGE("unable to shutdown volume '%s'", v->mount_point); pthread_mutex_unlock(&v->lock); } } return 0; }
static int do_set_ums_enable(char *cmd) { #ifdef ADD_ISO static struct devmapping *loop = NULL; static struct devmapping loopback; static char devpath[4096]; // TODO: lun_syspath を変更する必要がある。 static char *lun_syspath = "/sys/devices/platform/s3c-usbgadget/gadget/lun0/file"; LOG_VOL("do_set_ums_enable:%s:%s\n", cmd, lun_syspath); if (!strcmp(cmd, VOLD_CMD_ENABLE_UMS_SD)) { loop = NULL; LOG_VOL("do_set_ums_enable:%s\n", VOLD_CMD_ENABLE_UMS_SD); return volmgr_enable_ums(true); } else if (!strncmp(cmd, VOLD_CMD_ENABLE_UMS_CD, strlen(VOLD_CMD_ENABLE_UMS_CD))) { /* ループバックデバイスパスの取得 */ LOG_VOL("do_set_ums_enable:%s\n", VOLD_CMD_ENABLE_UMS_CD); int rc = 0; memset(devpath, 0, 4096); memcpy(devpath, &cmd[strlen(VOLD_CMD_ENABLE_UMS_CD)], strlen(&cmd[strlen(VOLD_CMD_ENABLE_UMS_CD)])); LOG_VOL("do_set_ums_enable devpath=%s\n", devpath); /* ループバックデバイスの登録 */ loopback.src_type = dmsrc_loopback; loopback.type_data.loop.loop_src = devpath; loopback.type_data.loop.loop_dev = NULL; rc = loopback_start(&loopback); if (rc) { LOGE("loopback_start err=%d\n", rc); } /* ループバックデバイスパスをカーネルに追加する */ /* カーネルにはloopback dev登録であることを知らせナイトね */ rc = ums_enable(loopback.type_data.loop.loop_dev, lun_syspath, false); if (rc) { LOGE("ums_enable err=%d\n", rc); } loop = &loopback; return 0; } else { int ret = 0; LOG_VOL("do_set_ums_enable:%s\n", "disable_ums\n"); if (loop) { int rc; rc = ums_disable(lun_syspath); if (rc) { LOGE("ums_enable err=%d\n", rc); } /* ループバックデバイスの解除 */ rc = loopback_stop(loop); if (rc) { LOGE("loopback_stop err=%d\n", rc); } else { free(loopback.type_data.loop.loop_dev); loopback.type_data.loop.loop_dev = NULL; } } else { ret = volmgr_enable_ums(false); } loop = NULL; return ret; } #else if (!strcmp(cmd, VOLD_CMD_ENABLE_UMS)) return volmgr_enable_ums(true); return volmgr_enable_ums(false); #endif /* ADD_ISO */ }