81
81
hints.ai_flags = AI_NUMERICSERV;
83
83
if ((err = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
84
LOG(log_error, logtype_default, "tsock_getfd: getaddrinfo: CNID server %s:%s : %s\n", host, port, gai_strerror(err));
84
LOG(log_error, logtype_default, "tsock_getfd: getaddrinfo: CNID server %s:%s : %s\n",
85
host, port, gai_strerror(err));
88
89
/* loop through all the results and bind to the first we can */
89
90
for (p = servinfo; p != NULL; p = p->ai_next) {
90
91
if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
91
LOG(log_info, logtype_default, "tsock_getfd: socket CNID server %s:: %s", host, strerror(errno));
92
LOG(log_info, logtype_default, "tsock_getfd: socket CNID server %s:: %s",
93
host, strerror(errno));
96
98
if (setsockopt(sock, SOL_TCP, TCP_NODELAY, &attr, sizeof(attr)) == -1) {
97
LOG(log_error, logtype_cnid, "getfd: set TCP_NODELAY CNID server %s: %s", host, strerror(errno));
102
tv.tv_sec = SOCK_DELAY;
104
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
105
LOG(log_error, logtype_cnid, "getfd: set SO_RCVTIMEO CNID server %s: %s", host, strerror(errno));
110
tv.tv_sec = SOCK_DELAY;
112
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) {
113
LOG(log_error, logtype_cnid, "getfd: set SO_SNDTIMEO CNID server %s: %s", host, strerror(errno));
99
LOG(log_error, logtype_cnid, "getfd: set TCP_NODELAY CNID server %s: %s",
100
host, strerror(errno));
106
if (setnonblock(sock, 1) != 0) {
107
LOG(log_error, logtype_cnid, "getfd: setnonblock: %s", strerror(err));
118
113
if (connect(sock, p->ai_addr, p->ai_addrlen) == -1) {
122
LOG(log_error, logtype_cnid, "getfd: connect CNID server %s: %s", host, strerror(err));
114
if (errno == EINPROGRESS) {
117
tv.tv_sec = 5; /* give it five seconds ... */
122
if ((err = select(sock + 1, NULL, &wfds, NULL, &tv)) == 0) {
124
LOG(log_error, logtype_cnid, "getfd: select timed out for CNID server %s",
132
LOG(log_error, logtype_cnid, "getfd: select failed for CNID server %s",
139
if ( ! FD_ISSET(sock, &wfds)) {
141
LOG(log_error, logtype_cnid, "getfd: socket not ready connecting to %s",
148
if ((err = getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen)) != 0 || optval != 0) {
150
/* somethings very wrong */
151
LOG(log_error, logtype_cnid, "getfd: getsockopt error with CNID server %s: %s",
152
host, strerror(errno));
155
LOG(log_error, logtype_cnid, "getfd: getsockopt says: %s",
163
LOG(log_error, logtype_cnid, "getfd: connect CNID server %s: %s",
164
host, strerror(errno));
126
171
/* We've got a socket */
130
175
freeaddrinfo(servinfo);
133
LOG(log_error, logtype_cnid, "tsock_getfd: no suitable network config from CNID server %s:%s", host, port);
179
LOG(log_error, logtype_cnid, "tsock_getfd: no suitable network config from CNID server (%s:%s): %s",
180
host, port, strerror(errno));
140
/* --------------------- */
141
static int write_vec(int fd, struct iovec *iov, size_t towrite)
188
* Write "towrite" bytes using writev on non-blocking fd
190
* Every short write is considered an error, transmit can handle that.
192
* @param fd (r) socket fd which must be non-blocking
193
* @param iov (r) iovec for writev
194
* @param towrite (r) number of bytes in all iovec elements
195
* @param vecs (r) number of iovecs in array
197
* @returns "towrite" bytes written or -1 on error
199
static int write_vec(int fd, struct iovec *iov, ssize_t towrite, int vecs)
146
LOG(log_maxdebug, logtype_cnid, "write_vec: request to write %d bytes", towrite);
148
len1 = iov[1].iov_len;
149
while (towrite > 0) {
150
if (((len = writev(fd, iov, 2)) == -1 && errno == EINTR) || !len)
153
if ((size_t)len == towrite) /* wrote everything out */
206
if (((len = writev(fd, iov, vecs)) == -1 && errno == EINTR))
209
if ((! slept) && len == -1 && errno == EAGAIN) {
211
while ((sleepsecs = sleep(sleepsecs)));
216
if (len == towrite) /* wrote everything out */
155
else if (len < 0) { /* error */
160
if (towrite > len1) { /* skip part of header */
161
iov[0].iov_base = (char *) iov[0].iov_base + len;
162
iov[0].iov_len -= len;
163
} else { /* skip to data */
164
if (iov[0].iov_len) {
165
len -= iov[0].iov_len;
168
iov[1].iov_base = (char *) iov[1].iov_base + len;
169
iov[1].iov_len -= len;
220
LOG(log_error, logtype_cnid, "write_vec: %s", strerror(errno));
222
LOG(log_error, logtype_cnid, "write_vec: short write: %d", len);
173
LOG(log_maxdebug, logtype_cnid, "write_vec: wrote %d bytes", towrite);
226
LOG(log_maxdebug, logtype_cnid, "write_vec: wrote %d bytes", len);
178
231
/* --------------------- */
213
266
struct iovec iov[2];
216
LOG(log_maxdebug, logtype_cnid, "send_packet: BEGIN");
218
if (!rqst->namelen) {
219
if (write(db->fd, rqst, sizeof(struct cnid_dbd_rqst)) != sizeof(struct cnid_dbd_rqst)) {
220
LOG(log_warning, logtype_cnid, "send_packet: Error/short write rqst (db_dir %s): %s",
221
db->db_dir, strerror(errno));
224
LOG(log_maxdebug, logtype_cnid, "send_packet: OK");
228
270
iov[0].iov_base = rqst;
229
271
iov[0].iov_len = sizeof(struct cnid_dbd_rqst);
231
iov[1].iov_base = rqst->name;
232
iov[1].iov_len = rqst->namelen;
234
towrite = sizeof(struct cnid_dbd_rqst) +rqst->namelen;
236
if (write_vec(db->fd, iov, towrite) < 0) {
272
towrite = sizeof(struct cnid_dbd_rqst);
276
iov[1].iov_base = rqst->name;
277
iov[1].iov_len = rqst->namelen;
278
towrite += rqst->namelen;
282
if (write_vec(db->fd, iov, towrite, vecs) != towrite) {
237
283
LOG(log_warning, logtype_cnid, "send_packet: Error writev rqst (db_dir %s): %s",
238
284
db->db_dir, strerror(errno));
242
LOG(log_maxdebug, logtype_cnid, "send_packet: OK");
288
LOG(log_maxdebug, logtype_cnid, "send_packet: {done}");
302
LOG(log_maxdebug, logtype_cnid, "dbd_rpc: BEGIN");
304
326
if (send_packet(db, rqst) < 0) {
307
329
len = rply->namelen;
308
330
nametmp = rply->name;
310
ret = dbd_read(db->fd, rply, sizeof(struct cnid_dbd_rply));
332
ret = readt(db->fd, rply, sizeof(struct cnid_dbd_rply), 0, ONE_DELAY);
312
334
if (ret != sizeof(struct cnid_dbd_rply)) {
313
335
LOG(log_error, logtype_cnid, "dbd_rpc: Error reading header from fd (db_dir %s): %s",
314
db->db_dir, ret == -1?strerror(errno):"closed");
336
db->db_dir, ret == -1 ? strerror(errno) : "closed");
315
337
rply->name = nametmp;
322
344
db->db_dir, rply->name, rply->namelen, len);
325
if (rply->namelen && (ret = dbd_read(db->fd, rply->name, rply->namelen)) != (ssize_t)rply->namelen) {
347
if (rply->namelen && (ret = readt(db->fd, rply->name, rply->namelen, 0, ONE_DELAY)) != (ssize_t)rply->namelen) {
326
348
LOG(log_error, logtype_cnid, "dbd_rpc: Error reading name from fd (db_dir %s): %s",
327
349
db->db_dir, ret == -1?strerror(errno):"closed");
331
LOG(log_maxdebug, logtype_cnid, "dbd_rpc: END");
353
LOG(log_maxdebug, logtype_cnid, "dbd_rpc: {done}");
376
396
LOG(log_debug7, logtype_cnid, "transmit: ... OK.");
397
} else { /* db->notfirst == 0 */
379
398
db->notfirst = 1;
380
399
if (db->client_stamp)
381
400
memcpy(db->client_stamp, stamp, ADEDLEN_PRIVSYN);
382
401
memcpy(db->stamp, stamp, ADEDLEN_PRIVSYN);
384
LOG(log_debug, logtype_cnid, "transmit: succesfully attached to cnid_dbd for volume '%s' with stamp '%08lx'.",
403
LOG(log_debug, logtype_cnid, "transmit: attached to '%s', stamp: '%08lx'.",
385
404
db->db_dir, *(uint64_t *)stamp);
387
406
if (!dbd_rpc(db, rqst, rply)) {
388
LOG(log_debug7, logtype_cnid, "transmit: END OK");
407
LOG(log_maxdebug, logtype_cnid, "transmit: {done}");
769
793
/* ---------------------- */
794
int cnid_dbd_find(struct _cnid_db *cdb, char *name, size_t namelen, void *buffer, size_t buflen)
797
struct cnid_dbd_rqst rqst;
798
struct cnid_dbd_rply rply;
801
if (!cdb || !(db = cdb->_private) || !name) {
802
LOG(log_error, logtype_cnid, "cnid_find: Parameter error");
803
errno = CNID_ERR_PARAM;
807
if (namelen > MAXPATHLEN) {
808
LOG(log_error, logtype_cnid, "cnid_find: Path name is too long");
809
errno = CNID_ERR_PATH;
813
LOG(log_debug, logtype_cnid, "cnid_find(\"%s\")", name);
816
rqst.op = CNID_DBD_OP_SEARCH;
819
rqst.namelen = namelen;
822
rply.namelen = buflen;
824
if (transmit(db, &rqst, &rply) < 0) {
829
switch (rply.result) {
830
case CNID_DBD_RES_OK:
831
count = rply.namelen / sizeof(cnid_t);
832
LOG(log_debug, logtype_cnid, "cnid_find: got %d matches", count);
834
case CNID_DBD_RES_NOTFOUND:
837
case CNID_DBD_RES_ERR_DB:
848
/* ---------------------- */
770
849
int cnid_dbd_update(struct _cnid_db *cdb, const cnid_t id, const struct stat *st,
771
850
const cnid_t did, char *name, const size_t len)