Пример #1
0
errno_t iSCSIDCreateArrayofActivePortalsForTarget(int fd,struct iSCSIDCmdCreateArrayOfActivePortalsForTarget * cmd)
{
    CFArrayRef sessionIds = iSCSICreateArrayOfSessionIds();
    CFIndex sessionCount = CFArrayGetCount(sessionIds);

    // Prepare an array to hold our targets
    CFMutableArrayRef activeTargets = CFArrayCreateMutable(kCFAllocatorDefault,
                                      sessionCount,
                                      &kCFTypeArrayCallBacks);

    // Get target object for each active session and add to array
    for(CFIndex idx = 0; idx < sessionCount; idx++)
    {
        iSCSITargetRef target = iSCSICreateTargetForSessionId((SID)CFArrayGetValueAtIndex(sessionIds,idx));
        CFArrayAppendValue(activeTargets,target);
        iSCSITargetRelease(target);
    }

    // Serialize and send array
    CFDataRef data = CFPropertyListCreateData(kCFAllocatorDefault,
                     (CFPropertyListRef) activeTargets,
                     kCFPropertyListBinaryFormat_v1_0,0,NULL);
    CFRelease(activeTargets);

    // Send response header
    struct iSCSIDRspCreateArrayOfActiveTargets rsp = iSCSIDRspCreateArrayOfActiveTargetsInit;
    if(data)
        rsp.dataLength = (UInt32)CFDataGetLength(data);
    else
        rsp.dataLength = 0;

    if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp))
    {
        if(data)
            CFRelease(data);
        return EAGAIN;
    }

    if(data)
    {
        if(send(fd,CFDataGetBytePtr(data),rsp.dataLength,0) != rsp.dataLength)
        {
            CFRelease(data);
            return EAGAIN;
        }

        CFRelease(data);
    }
    return 0;
}
/*! Retrieves a list of targets available from a give portal.
 *  @param handle a handle to a daemon connection.
 *  @param portal the iSCSI portal to look for targets.
 *  @param authMethod the preferred authentication method.
 *  @param statusCode iSCSI response code indicating operation status.
 *  @return an error code indicating whether the operation was successful. */
errno_t iSCSIDaemonQueryTargetForAuthMethod(iSCSIDaemonHandle handle,
                                            iSCSIPortalRef portal,
                                            CFStringRef targetIQN,
                                            enum iSCSIAuthMethods * authMethod,
                                            enum iSCSILoginStatusCode * statusCode)
{
    // Validate inputs
    if(handle < 0 || !portal || !targetIQN || !authMethod || !statusCode)
        return EINVAL;
    
    // Setup a target object with the target name
    iSCSIMutableTargetRef target = iSCSITargetCreateMutable();
    iSCSITargetSetIQN(target,targetIQN);
    
    // Generate data to transmit (no longer need target object after this)
    CFDataRef targetData = iSCSITargetCreateData(target);
    iSCSITargetRelease(target);
    
    CFDataRef portalData = iSCSIPortalCreateData(portal);
    
    // Create command header to transmit
    iSCSIDMsgQueryTargetForAuthMethodCmd cmd = iSCSIDMsgQueryTargetForAuthMethodCmdInit;
    cmd.portalLength = (UInt32)CFDataGetLength(portalData);
    cmd.targetLength = (UInt32)CFDataGetLength(targetData);
    
    if(iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd,targetData,portalData,NULL))
    {
        CFRelease(portalData);
        CFRelease(targetData);
        return EIO;
    }

    CFRelease(portalData);
    CFRelease(targetData);
    iSCSIDMsgQueryTargetForAuthMethodRsp rsp;
    
    if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp))
        return EIO;
    
    *authMethod = rsp.authMethod;
    *statusCode = rsp.statusCode;
    
    return rsp.errorCode;
}
Пример #3
0
errno_t iSCSIDLogout(int fd,struct iSCSIDCmdLogout * cmd)
{
    // Grab objects from stream
    iSCSITargetRef target = iSCSIDCreateObjectFromSocket(fd,cmd->targetLength,
                            (void *(* )(CFDataRef))&iSCSITargetCreateWithData);

    iSCSIPortalRef portal = iSCSIDCreateObjectFromSocket(fd,cmd->portalLength,
                            (void *(* )(CFDataRef))&iSCSIPortalCreateWithData);

    SID sessionId = kiSCSIInvalidSessionId;
    CID connectionId = kiSCSIInvalidConnectionId;
    enum iSCSILogoutStatusCode statusCode = kiSCSILogoutInvalidStatusCode;

    // Error code to return to daemon's client
    errno_t errorCode = 0;

    // Synchronize property list
    iSCSIPLSynchronize();

    // See if there exists an active session for this target
    if((sessionId = iSCSIGetSessionIdForTarget(iSCSITargetGetIQN(target))) == kiSCSIInvalidSessionId)
    {
        //iSCSICtlDisplayError("The specified target has no active session.");
        errorCode = EINVAL;
    }

    // See if there exists an active connection for this portal
    if(!errorCode && portal)
        connectionId = iSCSIGetConnectionIdForPortal(sessionId,portal);

    // If the portal was specified and a connection doesn't exist for it...
    if(!errorCode && portal && connectionId == kiSCSIInvalidConnectionId)
    {
        //iSCSICtlDisplayError("The specified portal has no active connections.");
        errorCode = EINVAL;
    }

    // At this point either the we logout the session or just the connection
    // associated with the specified portal, if one was specified
    if(!errorCode)
    {
        if(!portal)
            errorCode = iSCSILogoutSession(sessionId,&statusCode);
        else
            errorCode = iSCSILogoutConnection(sessionId,connectionId,&statusCode);
        /*
         if(!error)
         iSCSICtlDisplayLogoutStatus(statusCode,target,portal);
         else
         iSCSICtlDisplayError(strerror(error));*/
    }

    if(portal)
        iSCSIPortalRelease(portal);
    iSCSITargetRelease(target);

    // Compose a response to send back to the client
    struct iSCSIDRspLogout rsp = iSCSIDRspLogoutInit;
    rsp.errorCode = errorCode;
    rsp.statusCode = statusCode;

    if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp))
        return EAGAIN;

    return 0;
}