Example #1
0
static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd)
#endif
{
    int                 rc;
    PVBOXGUESTSESSION   pSession;

    LogFlow(("vgdrvFreeBSDOpen:\n"));

    /*
     * Try grab it (we don't grab the giant, remember).
     */
    if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, (void *)0x42, NULL))
        return EBUSY;

    /*
     * Create a new session.
     */
    rc = VGDrvCommonCreateUserSession(&g_DevExt, &pSession);
    if (RT_SUCCESS(rc))
    {
        if (ASMAtomicCmpXchgPtr(&pDev->si_drv1, pSession, (void *)0x42))
        {
            Log(("vgdrvFreeBSDOpen: success - g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
            ASMAtomicIncU32(&cUsers);
            return 0;
        }

        VGDrvCommonCloseSession(&g_DevExt, pSession);
    }

    LogRel(("vgdrvFreeBSDOpen: failed. rc=%d\n", rc));
    return RTErrConvertToErrno(rc);
}
Example #2
0
/**
 * User context entry points
 *
 * @remarks fFlags are the flags passed to open() or to ldi_open_by_name.  In
 *          the latter case the FKLYR flag is added to indicate that the caller
 *          is a kernel component rather than user land.
 */
static int vgdrvSolarisOpen(dev_t *pDev, int fFlags, int fType, cred_t *pCred)
{
    int                 rc;
    PVBOXGUESTSESSION   pSession = NULL;

    LogFlow(("vgdrvSolarisOpen:\n"));

    /*
     * Verify we are being opened as a character device.
     */
    if (fType != OTYP_CHR)
        return EINVAL;

    vboxguest_state_t *pState = NULL;
    unsigned iOpenInstance;
    for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
    {
        if (    !ddi_get_soft_state(g_pvgdrvSolarisState, iOpenInstance) /* faster */
            &&  ddi_soft_state_zalloc(g_pvgdrvSolarisState, iOpenInstance) == DDI_SUCCESS)
        {
            pState = ddi_get_soft_state(g_pvgdrvSolarisState, iOpenInstance);
            break;
        }
    }
    if (!pState)
    {
        Log(("vgdrvSolarisOpen: too many open instances."));
        return ENXIO;
    }

    /*
     * Create a new session.
     */
    if (!(fFlags & FKLYR))
        rc = VGDrvCommonCreateUserSession(&g_DevExt, &pSession);
    else
        rc = VGDrvCommonCreateKernelSession(&g_DevExt, &pSession);
    if (RT_SUCCESS(rc))
    {
        if (!(fFlags & FKLYR))
            pState->pvProcRef = proc_ref();
        else
            pState->pvProcRef = NULL;
        pState->pSession = pSession;
        *pDev = makedevice(getmajor(*pDev), iOpenInstance);
        Log(("vgdrvSolarisOpen: pSession=%p pState=%p pid=%d\n", pSession, pState, (int)RTProcSelf()));
        return 0;
    }

    /* Failed, clean up. */
    ddi_soft_state_free(g_pvgdrvSolarisState, iOpenInstance);

    LogRel((DEVICE_NAME "::Open: VGDrvCommonCreateUserSession failed. rc=%d\n", rc));
    return EFAULT;
}
Example #3
0
/**
 * Driver open hook.
 *
 * @param name          The name of the device as returned by publish_devices.
 * @param flags         Open flags.
 * @param cookie        Where to store the session pointer.
 *
 * @return Haiku status code.
 */
static status_t vgdrvHaikuOpen(const char *name, uint32 flags, void **cookie)
{
    int rc;
    PVBOXGUESTSESSION pSession;

    LogFlow((DRIVER_NAME ":vgdrvHaikuOpen\n"));

    /*
     * Create a new session.
     */
    rc = VGDrvCommonCreateUserSession(&g_DevExt, &pSession);
    if (RT_SUCCESS(rc))
    {
        Log((DRIVER_NAME ":vgdrvHaikuOpen success: g_DevExt=%p pSession=%p rc=%d pid=%d\n",&g_DevExt, pSession, rc,(int)RTProcSelf()));
        ASMAtomicIncU32(&cUsers);
        *cookie = pSession;
        return B_OK;
    }

    LogRel((DRIVER_NAME ":vgdrvHaikuOpen: failed. rc=%d\n", rc));
    return RTErrConvertToErrno(rc);
}
/**
 * Device open. Called on open /dev/vboxdrv
 *
 * @param   pInode      Pointer to inode info structure.
 * @param   pFilp       Associated file pointer.
 */
static int vgdrvLinuxOpen(struct inode *pInode, struct file *pFilp)
{
    int                 rc;
    PVBOXGUESTSESSION   pSession;
    Log((DEVICE_NAME ": pFilp=%p pid=%d/%d %s\n", pFilp, RTProcSelf(), current->pid, current->comm));

    /*
     * Call common code to create the user session. Associate it with
     * the file so we can access it in the other methods.
     */
    rc = VGDrvCommonCreateUserSession(&g_DevExt, &pSession);
    if (RT_SUCCESS(rc))
    {
        pFilp->private_data = pSession;
        if (MINOR(pInode->i_rdev) == g_MiscDeviceUser.minor)
            pSession->fUserSession = true;
    }

    Log(("vgdrvLinuxOpen: g_DevExt=%p pSession=%p rc=%d/%d (pid=%d/%d %s)\n",
         &g_DevExt, pSession, rc, vgdrvLinuxConvertToNegErrno(rc), RTProcSelf(), current->pid, current->comm));
    return vgdrvLinuxConvertToNegErrno(rc);
}
/**
 * User context entry points
 *
 * @remarks fFlags are the flags passed to open() or to ldi_open_by_name.  In
 *          the latter case the FKLYR flag is added to indicate that the caller
 *          is a kernel component rather than user land.
 */
static int vgdrvSolarisOpen(dev_t *pDev, int fFlags, int fType, cred_t *pCred)
{
    int                 rc;
    PVBOXGUESTSESSION   pSession = NULL;

    LogFlow(("vgdrvSolarisOpen:\n"));

    /*
     * Verify we are being opened as a character device.
     */
    if (fType != OTYP_CHR)
        return EINVAL;

    vboxguest_state_t *pState = NULL;
    unsigned iOpenInstance;
    for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
    {
        if (    !ddi_get_soft_state(g_pvgdrvSolarisState, iOpenInstance) /* faster */
            &&  ddi_soft_state_zalloc(g_pvgdrvSolarisState, iOpenInstance) == DDI_SUCCESS)
        {
            pState = ddi_get_soft_state(g_pvgdrvSolarisState, iOpenInstance);
            break;
        }
    }
    if (!pState)
    {
        Log(("vgdrvSolarisOpen: too many open instances."));
        return ENXIO;
    }

    /*
     * Create a new session.
     *
     * Note! The devfs inode with the gid isn't readily available here, so we cannot easily
     *       to the vbox group detection like on linux.  Read config instead?
     */
    if (!(fFlags & FKLYR))
    {
        uint32_t fRequestor = VMMDEV_REQUESTOR_USERMODE | VMMDEV_REQUESTOR_TRUST_NOT_GIVEN;
        if (crgetruid(pCred) == 0)
            fRequestor |= VMMDEV_REQUESTOR_USR_ROOT;
        else
            fRequestor |= VMMDEV_REQUESTOR_USR_USER;
        if (secpolicy_coreadm(pCred) == 0)
            fRequestor |= VMMDEV_REQUESTOR_GRP_WHEEL;
        /** @todo is there any way of detecting that the process belongs to someone on the physical console?
         * secpolicy_console() [== PRIV_SYS_DEVICES] doesn't look quite right, or does it? */
        fRequestor |= VMMDEV_REQUESTOR_CON_DONT_KNOW;
        fRequestor |= VMMDEV_REQUESTOR_NO_USER_DEVICE; /** @todo implement vboxuser device node. */

        rc = VGDrvCommonCreateUserSession(&g_DevExt, fRequestor, &pSession);
    }
    else
        rc = VGDrvCommonCreateKernelSession(&g_DevExt, &pSession);
    if (RT_SUCCESS(rc))
    {
        if (!(fFlags & FKLYR))
            pState->pvProcRef = proc_ref();
        else
            pState->pvProcRef = NULL;
        pState->pSession = pSession;
        *pDev = makedevice(getmajor(*pDev), iOpenInstance);
        Log(("vgdrvSolarisOpen: pSession=%p pState=%p pid=%d\n", pSession, pState, (int)RTProcSelf()));
        return 0;
    }

    /* Failed, clean up. */
    ddi_soft_state_free(g_pvgdrvSolarisState, iOpenInstance);

    LogRel((DEVICE_NAME "::Open: VGDrvCommonCreateUserSession failed. rc=%d\n", rc));
    return EFAULT;
}