Annotation of libaitrpc/src/blob.c, revision 1.1.2.12

1.1.2.1   misho       1: #include "global.h"
                      2: 
                      3: 
1.1.2.2   misho       4: /*
1.1.2.4   misho       5:  * rpc_srv_blobCreate() Create map blob to memory region and return object
                      6:  * @srv = RPC Server instance
                      7:  * @len = BLOB length object
                      8:  * return: NULL error or !=NULL allocated BLOB object
                      9:  */
                     10: inline rpc_blob_t *
                     11: rpc_srv_blobCreate(rpc_srv_t * __restrict srv, int len)
                     12: {
                     13:        rpc_blob_t *blob = NULL;
                     14:        char szFName[MAXPATHLEN];
                     15:        int f;
1.1.2.7   misho      16:        u_int rnd;
                     17: 
                     18:        srandomdev();
                     19:        srandom(getpid() ^ time(NULL));
                     20: again:
                     21:        rnd = random() % UINT_MAX;
1.1.2.4   misho      22: 
                     23:        memset(szFName, 0, MAXPATHLEN);
1.1.2.7   misho      24:        snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, rnd);
                     25:        f = open(szFName, O_CREAT | O_EXCL | O_RDWR, 0600);
1.1.2.4   misho      26:        if (f == -1) {
1.1.2.7   misho      27:                if (errno == EEXIST)
                     28:                        goto again;
                     29: 
1.1.2.4   misho      30:                LOGERR;
                     31:                return NULL;
                     32:        }
                     33:        if (lseek(f, len - 1, SEEK_SET) == -1) {
                     34:                LOGERR;
                     35:                close(f);
                     36:                unlink(szFName);
                     37:                return NULL;
                     38:        } else
                     39:                write(f, "", 1);
                     40: 
                     41:        blob = malloc(sizeof(rpc_blob_t));
                     42:        if (!blob) {
                     43:                LOGERR;
                     44:                close(f);
                     45:                unlink(szFName);
                     46:                return NULL;
                     47:        }
                     48: 
                     49:        blob->blob_data = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
                     50:        if (blob->blob_data == MAP_FAILED) {
                     51:                LOGERR;
                     52:                free(blob);
                     53:                close(f);
                     54:                unlink(szFName);
                     55:                return NULL;
                     56:        } else
                     57:                close(f);
                     58: 
                     59:        blob->blob_len = len;
1.1.2.7   misho      60:        blob->blob_var = rnd;
1.1.2.4   misho      61:        return blob;
                     62: }
                     63: 
                     64: /*
1.1.2.2   misho      65:  * rpc_srv_blobMap() Map blob to memory region 
                     66:  * @srv = RPC Server instance
                     67:  * @blob = Map to this BLOB element
                     68:  * return: -1 error or 0 ok
                     69:  */
                     70: inline int
                     71: rpc_srv_blobMap(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
                     72: {
                     73:        int f;
                     74:        char szFName[MAXPATHLEN];
                     75: 
                     76:        if (!blob) {
                     77:                rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
                     78:                return -1;
                     79:        }
                     80: 
                     81:        memset(szFName, 0, MAXPATHLEN);
                     82:        snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, blob->blob_var);
1.1.2.8   misho      83:        f = open(szFName, O_RDWR);
1.1.2.2   misho      84:        if (f == -1) {
                     85:                LOGERR;
                     86:                return -1;
                     87:        }
                     88: 
1.1.2.12! misho      89:        blob->blob_data = mmap(NULL, blob->blob_len, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
1.1.2.2   misho      90:        if (blob->blob_data == MAP_FAILED) {
                     91:                LOGERR;
                     92:                close(f);
                     93:                blob->blob_data = NULL;
                     94:                return -1;
                     95:        } else {
                     96:                close(f);
1.1.2.4   misho      97: 
1.1.2.12! misho      98:                madvise(blob->blob_data, blob->blob_len, MADV_SEQUENTIAL);
1.1.2.2   misho      99:        }
                    100: 
                    101:        return 0;
                    102: }
                    103: 
                    104: /*
                    105:  * rpc_srv_blobUnmap() Unmap blob memory region 
                    106:  * @blob = Mapped BLOB element
                    107:  * return: none
                    108:  */
                    109: inline void
                    110: rpc_srv_blobUnmap(rpc_blob_t * __restrict blob)
                    111: {
                    112:        if (!blob || !blob->blob_data)
                    113:                rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
                    114:        else {
                    115:                munmap(blob->blob_data, blob->blob_len);
                    116:                blob->blob_data = NULL;
                    117:        }
                    118: }
                    119: 
                    120: /*
                    121:  * rpc_srv_blobFree() Free blob from disk & memory
                    122:  * @srv = RPC Server instance
                    123:  * @blob = Mapped BLOB element
                    124:  * return: -1 error or 0 ok
                    125:  */
                    126: inline int
                    127: rpc_srv_blobFree(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
                    128: {
                    129:        char szFName[MAXPATHLEN];
                    130: 
                    131:        if (!blob) {
                    132:                rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
                    133:                return -1;
                    134:        }
                    135: 
                    136:        if (blob->blob_data)
                    137:                rpc_srv_blobUnmap(blob);
                    138: 
                    139:        memset(szFName, 0, MAXPATHLEN);
                    140:        snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, blob->blob_var);
                    141:        if (remove(szFName) == -1) {
                    142:                LOGERR;
                    143:                return -1;
                    144:        }
                    145: 
                    146:        return 0;
                    147: }
                    148: 
                    149: // ------------------------------------------------------------
                    150: 
1.1.2.3   misho     151: /*
                    152:  * rpc_srv_sendBLOB() Send mapped BLOB to client
                    153:  * @cli = Client instance
                    154:  * @blob = Mapped BLOB element
                    155:  * return: -1 error, 0 ok
                    156:  */
1.1.2.2   misho     157: int
1.1.2.3   misho     158: rpc_srv_sendBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
1.1.2.2   misho     159: {
1.1.2.3   misho     160:        int ret, len;
                    161:        uint8_t *pos;
1.1.2.2   misho     162: 
1.1.2.3   misho     163:        if (!cli || !blob || !blob->blob_data) {
1.1.2.2   misho     164:                rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
                    165:                return -1;
                    166:        }
                    167: 
1.1.2.3   misho     168:        for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len)
                    169:                if ((len = send(cli->cli_sock, pos, ret > BLOBSIZ ? BLOBSIZ : ret, 0)) == -1) {
                    170:                        LOGERR;
                    171:                        return -1;
                    172:                }
1.1.2.2   misho     173: 
1.1.2.3   misho     174:        return ret;
                    175: }
                    176: 
                    177: /*
                    178:  * rpc_srv_recvBLOB() Receive BLOB from client
                    179:  * @cli = Client instance
1.1.2.4   misho     180:  * @blob = Mapped BLOB element
                    181:  * return: -1 error, 0 ok, >0 unreceived data from client, may be error?
1.1.2.3   misho     182:  */
                    183: int
1.1.2.4   misho     184: rpc_srv_recvBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
1.1.2.3   misho     185: {
                    186:        int ret, len;
                    187:        uint8_t *pos;
1.1.2.4   misho     188:        fd_set fds;
                    189:        struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.3   misho     190: 
1.1.2.4   misho     191:        if (!cli || !blob || !blob->blob_data) {
1.1.2.3   misho     192:                rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
                    193:                return -1;
1.1.2.4   misho     194:        }
                    195: 
                    196:        for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len) {
                    197:                FD_ZERO(&fds);
                    198:                FD_SET(cli->cli_sock, &fds);
                    199:                len = select(cli->cli_sock + 1, &fds, NULL, NULL, &tv);
                    200:                if (len < 1) {
                    201:                        LOGERR;
                    202:                        return -1;
                    203:                }
1.1.2.3   misho     204: 
1.1.2.4   misho     205:                if ((len = recv(cli->cli_sock, pos, BLOBSIZ, 0)) == -1) {
                    206:                        LOGERR;
                    207:                        return -1;
                    208:                }
                    209:        }
1.1.2.3   misho     210: 
                    211:        return ret;
1.1.2.2   misho     212: }
1.1.2.5   misho     213: 
                    214: // ------------------------------------------------------------
                    215: 
                    216: /*
                    217:  * rpc_cli_sendBLOB() Send BLOB to server
                    218:  * @cli = Client instance
                    219:  * @var = BLOB variable
                    220:  * @data = BLOB data
1.1.2.6   misho     221:  * return: -1 error, 0 ok, 1 remote error
1.1.2.5   misho     222:  */
                    223: int
                    224: rpc_cli_sendBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void * __restrict data)
                    225: {
                    226:        int ret, len;
                    227:        uint8_t *pos;
1.1.2.6   misho     228:        struct tagBLOBHdr hdr;
                    229:        fd_set fds;
                    230:        struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.5   misho     231: 
                    232:        if (!cli || !var || !data) {
                    233:                rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
                    234:                return -1;
                    235:        }
                    236: 
1.1.2.6   misho     237:        memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
                    238:        hdr.hdr_cmd = set;
1.1.2.10  misho     239:        hdr.hdr_var = 0;
1.1.2.11  misho     240:        hdr.hdr_ret = 0;
1.1.2.6   misho     241:        hdr.hdr_len = var->val_len;
                    242:        if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
                    243:                LOGERR;
                    244:                return -1;
                    245:        }
                    246: 
1.1.2.5   misho     247:        for (ret = var->val_len, pos = data; ret > 0; ret -= len, pos += len)
                    248:                if ((len = send(cli->cli_sock, pos, ret > BLOBSIZ ? BLOBSIZ : ret, 0)) == -1) {
                    249:                        LOGERR;
                    250:                        return -1;
                    251:                }
                    252: 
1.1.2.6   misho     253:        FD_ZERO(&fds);
                    254:        FD_SET(cli->cli_sock, &fds);
                    255:        switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
                    256:                case -1:
                    257:                        LOGERR;
                    258:                        return -1;
                    259:                case 0:
                    260:                        rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
                    261:                        return -1;
                    262:        }
1.1.2.10  misho     263:        if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
1.1.2.6   misho     264:                LOGERR;
                    265:                return -1;
                    266:        }
1.1.2.7   misho     267:        if (hdr.hdr_cmd != error) {
                    268:                if (hdr.hdr_len != var->val_len) {
                    269:                        rpc_SetErr(EBADMSG, "Error:: Bad return length packet ...\n");
                    270:                        return -1;
                    271:                }
                    272: 
1.1.2.10  misho     273:                var->val.blob = hdr.hdr_var;
1.1.2.7   misho     274:        }
1.1.2.6   misho     275: 
                    276:        return hdr.hdr_cmd == error;
1.1.2.5   misho     277: }
                    278: 
                    279: /*
                    280:  * rpc_cli_recvBLOB() Receive BLOB from server
                    281:  * @cli = Client instance
                    282:  * @var = BLOB variable
                    283:  * @data = BLOB data, must be free after use!
1.1.2.10  misho     284:  * return: -1 error, 0 ok, 1 remote error
1.1.2.5   misho     285:  */
                    286: int
                    287: rpc_cli_recvBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void ** data)
                    288: {
                    289:        int ret, len;
                    290:        uint8_t *pos;
                    291:        fd_set fds;
                    292:        struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
1.1.2.10  misho     293:        struct tagBLOBHdr hdr;
1.1.2.5   misho     294: 
                    295:        if (!cli || !var || !data) {
                    296:                rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
                    297:                return -1;
                    298:        }
                    299: 
                    300:        *data = malloc(var->val_len);
                    301:        if (!*data) {
                    302:                LOGERR;
                    303:                return -1;
                    304:        } else
                    305:                memset(*data, 0, var->val_len);
                    306: 
1.1.2.10  misho     307:        memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
                    308:        hdr.hdr_cmd = get;
                    309:        hdr.hdr_var = (uint32_t) RPC_GET_BLOB(var);
1.1.2.11  misho     310:        hdr.hdr_ret = 0;
1.1.2.10  misho     311:        hdr.hdr_len = 0;
                    312:        if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
                    313:                LOGERR;
                    314:                free(*data);
                    315:                *data = NULL;
                    316:                return -1;
                    317:        }
                    318: 
1.1.2.5   misho     319:        for (ret = var->val_len, pos = *data; ret > 0; ret -= len, pos += len) {
                    320:                FD_ZERO(&fds);
                    321:                FD_SET(cli->cli_sock, &fds);
                    322:                len = select(cli->cli_sock + 1, &fds, NULL, NULL, &tv);
                    323:                if (len < 1) {
                    324:                        LOGERR;
                    325:                        free(*data);
                    326:                        *data = NULL;
                    327:                        return -1;
                    328:                }
                    329: 
                    330:                if ((len = recv(cli->cli_sock, pos, BLOBSIZ, 0)) == -1) {
                    331:                        LOGERR;
                    332:                        free(*data);
                    333:                        *data = NULL;
                    334:                        return -1;
                    335:                }
                    336:        }
                    337: 
1.1.2.10  misho     338:        FD_ZERO(&fds);
                    339:        FD_SET(cli->cli_sock, &fds);
                    340:        switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
                    341:                case -1:
                    342:                        LOGERR;
                    343:                        free(*data);
                    344:                        *data = NULL;
                    345:                        return -1;
                    346:                case 0:
                    347:                        rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
                    348:                        free(*data);
                    349:                        *data = NULL;
                    350:                        return -1;
                    351:        }
                    352:        if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
                    353:                LOGERR;
                    354:                free(*data);
                    355:                *data = NULL;
                    356:                return -1;
                    357:        }
                    358:        if (hdr.hdr_cmd != error) {
                    359:                if (hdr.hdr_len != var->val_len) {
                    360:                        rpc_SetErr(EBADMSG, "Error:: Bad return length packet ...\n");
                    361:                        free(*data);
                    362:                        *data = NULL;
                    363:                        return -1;
                    364:                }
                    365:        }
                    366: 
                    367:        return hdr.hdr_cmd == error;
1.1.2.5   misho     368: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>