2 * 2008+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <sys/types.h>
28 #include "elliptics.h"
29 #include "elliptics/interface.h"
31 static int dnet_check_complete(struct dnet_net_state
*state
, struct dnet_cmd
*cmd
, void *priv
)
33 struct dnet_wait
*w
= priv
;
36 if (is_trans_destroyed(state
, cmd
)) {
37 dnet_wakeup(w
, w
->cond
++);
42 if (cmd
->size
== sizeof(struct dnet_check_reply
)) {
43 struct dnet_check_reply
*r
= (struct dnet_check_reply
*)(cmd
+ 1);
45 dnet_convert_check_reply(r
);
47 dnet_log(state
->n
, DNET_LOG_INFO
, "check: total: %d, completed: %d, errors: %d\n",
48 r
->total
, r
->completed
, r
->errors
);
51 w
->status
= cmd
->status
;
55 static int dnet_send_check_request(struct dnet_net_state
*st
, struct dnet_id
*id
,
56 struct dnet_wait
*w
, struct dnet_check_request
*r
)
58 struct dnet_trans_control ctl
;
62 memset(&ctl
, 0, sizeof(struct dnet_trans_control
));
64 memcpy(&ctl
.id
, id
, sizeof(struct dnet_id
));
65 ctl
.cmd
= DNET_CMD_LIST
;
66 ctl
.complete
= dnet_check_complete
;
68 ctl
.cflags
= DNET_FLAGS_NEED_ACK
| DNET_FLAGS_NOLOCK
;
71 localtime_r((time_t *)&r
->timestamp
, &tm
);
72 strftime(ctl_time
, sizeof(ctl_time
), "%F %R:%S %Z", &tm
);
74 snprintf(ctl_time
, sizeof(ctl_time
), "all records");
77 dnet_log(st
->n
, DNET_LOG_INFO
, "%s: check request: objects: %llu, threads: %llu, timestamp: %s, merge: %d\n",
78 dnet_state_dump_addr(st
), (unsigned long long)r
->obj_num
, (unsigned long long)r
->thread_num
,
79 ctl_time
, !!(r
->flags
& DNET_CHECK_MERGE
));
81 dnet_convert_check_request(r
);
84 ctl
.size
= sizeof(*r
) + r
->obj_num
* sizeof(struct dnet_id
) + r
->group_num
* sizeof(int);
86 return dnet_trans_alloc_send_state(st
, &ctl
);
89 int dnet_request_check(struct dnet_session
*s
, struct dnet_check_request
*r
)
91 struct dnet_node
*n
= s
->node
;
93 struct dnet_net_state
*st
;
97 w
= dnet_wait_alloc(0);
103 pthread_mutex_lock(&n
->state_lock
);
104 list_for_each_entry(g
, &n
->group_list
, group_entry
) {
105 list_for_each_entry(st
, &g
->state_list
, state_entry
) {
113 dnet_setup_id(&raw
, st
->idc
->group
->group_id
, st
->idc
->ids
[0].raw
.id
);
114 dnet_send_check_request(st
, &raw
, w
, r
);
118 pthread_mutex_unlock(&n
->state_lock
);
120 err
= dnet_wait_event(w
, w
->cond
== num
, &n
->wait_ts
);
136 dnet_log(n
, DNET_LOG_ERROR
, "Check exited with status %d\n", err
);