Clamonacc was missing scanning files when the system was under load,
due to scanning on file creation, which would occasionally scan before
the file had been written. This pr modifies clamonacc to scan when the file
is closed.
... | ... |
@@ -76,9 +76,10 @@ static int onas_send_stream(CURL *curl, const char *filename, int fd, int64_t ti |
76 | 76 |
{ |
77 | 77 |
uint32_t buf[BUFSIZ / sizeof(uint32_t)]; |
78 | 78 |
uint64_t len; |
79 |
- uint64_t todo = maxstream; |
|
80 | 79 |
int ret = 1; |
81 | 80 |
int close_flag = 0; |
81 |
+ STATBUF statbuf; |
|
82 |
+ uint64_t bytesRead = 0; |
|
82 | 83 |
|
83 | 84 |
if (-1 == fd) { |
84 | 85 |
if (NULL == filename) { |
... | ... |
@@ -94,30 +95,51 @@ static int onas_send_stream(CURL *curl, const char *filename, int fd, int64_t ti |
94 | 94 |
} |
95 | 95 |
} |
96 | 96 |
|
97 |
+ if (FSTAT(fd, &statbuf)){ |
|
98 |
+ logg("!onas_send_stream: Invalid args, bad file descriptor.\n"); |
|
99 |
+ ret = -1; |
|
100 |
+ goto strm_out; |
|
101 |
+ } |
|
102 |
+ |
|
103 |
+ if (S_ISDIR(statbuf.st_mode)){ |
|
104 |
+ ret = 0; |
|
105 |
+ goto strm_out; |
|
106 |
+ } |
|
107 |
+ |
|
108 |
+ if ((uint64_t) statbuf.st_size > maxstream){ |
|
109 |
+ ret = 0; |
|
110 |
+ goto strm_out; |
|
111 |
+ } |
|
112 |
+ |
|
97 | 113 |
if (onas_sendln(curl, "zINSTREAM", 10, timeout)) { |
98 | 114 |
ret = -1; |
99 | 115 |
goto strm_out; |
100 | 116 |
} |
101 | 117 |
|
102 |
- while ((len = read(fd, &buf[1], sizeof(buf) - sizeof(uint32_t))) > 0) { |
|
103 |
- if ((uint64_t)len > todo) len = todo; |
|
104 |
- buf[0] = htonl(len); |
|
105 |
- if (onas_sendln(curl, (const char *)buf, len + sizeof(uint32_t), timeout)) { |
|
118 |
+ len = statbuf.st_size; |
|
119 |
+ buf[0] = htonl(len); |
|
120 |
+ if (onas_sendln(curl, (const char *) buf, sizeof(uint32_t), timeout)){ |
|
121 |
+ ret = -1; |
|
122 |
+ goto strm_out; |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ while (bytesRead < len){ |
|
126 |
+ ssize_t ret = read(fd, buf, sizeof(buf)); |
|
127 |
+ if (ret < 0){ |
|
128 |
+ logg("!Failed to read from %s.\n", filename ? filename : "FD"); |
|
106 | 129 |
ret = -1; |
107 | 130 |
goto strm_out; |
108 |
- } |
|
109 |
- todo -= len; |
|
110 |
- if (!todo) { |
|
111 |
- len = 0; |
|
131 |
+ } else if (0 == ret){ |
|
112 | 132 |
break; |
113 | 133 |
} |
114 |
- } |
|
134 |
+ bytesRead += ret; |
|
115 | 135 |
|
116 |
- if (len) { |
|
117 |
- logg("!Failed to read from %s.\n", filename ? filename : "FD"); |
|
118 |
- ret = -1; |
|
119 |
- goto strm_out; |
|
136 |
+ if (onas_sendln(curl, (const char *) buf, ret, timeout)) { |
|
137 |
+ ret = -1; |
|
138 |
+ goto strm_out; |
|
139 |
+ } |
|
120 | 140 |
} |
141 |
+ |
|
121 | 142 |
*buf = 0; |
122 | 143 |
onas_sendln(curl, (const char *)buf, 4, timeout); |
123 | 144 |
|
... | ... |
@@ -72,6 +72,7 @@ static int onas_ddd_unwatch_hierarchy(const char *pathname, size_t len, int fd, |
72 | 72 |
|
73 | 73 |
static void onas_ddd_handle_in_moved_to(struct onas_context *ctx, const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask); |
74 | 74 |
static void onas_ddd_handle_in_create(struct onas_context *ctx, const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask); |
75 |
+static void onas_ddd_handle_in_close_write(struct onas_context *ctx, const char *child_path); |
|
75 | 76 |
static void onas_ddd_handle_in_moved_from(struct onas_context *ctx, const char *path, const char *child_path, const struct inotify_event *event, int wd); |
76 | 77 |
static void onas_ddd_handle_in_delete(struct onas_context *ctx, const char *path, const char *child_path, const struct inotify_event *event, int wd); |
77 | 78 |
static void onas_ddd_handle_extra_scanning(struct onas_context *ctx, const char *pathname, int extra_options); |
... | ... |
@@ -363,7 +364,7 @@ void *onas_ddd_th(void *arg) |
363 | 363 |
const struct optstruct *pt; |
364 | 364 |
const struct optstruct *pt_tmpdir; |
365 | 365 |
const char *clamd_tmpdir; |
366 |
- uint64_t in_mask = IN_ONLYDIR | IN_MOVE | IN_DELETE | IN_CREATE; |
|
366 |
+ uint64_t in_mask = IN_ONLYDIR | IN_MOVE | IN_DELETE | IN_CREATE | IN_CLOSE_WRITE; |
|
367 | 367 |
fd_set rfds; |
368 | 368 |
char buf[4096]; |
369 | 369 |
ssize_t bread; |
... | ... |
@@ -659,6 +660,9 @@ void *onas_ddd_th(void *arg) |
659 | 659 |
} else if (event->mask & IN_CREATE) { |
660 | 660 |
onas_ddd_handle_in_create(ctx, path, child_path, event, wd, in_mask); |
661 | 661 |
|
662 |
+ } else if (event->mask & IN_CLOSE_WRITE) { |
|
663 |
+ onas_ddd_handle_in_close_write(ctx, child_path); |
|
664 |
+ |
|
662 | 665 |
} else if (event->mask & IN_MOVED_TO) { |
663 | 666 |
onas_ddd_handle_in_moved_to(ctx, path, child_path, event, wd, in_mask); |
664 | 667 |
} |
... | ... |
@@ -708,26 +712,29 @@ static void onas_ddd_handle_in_create(struct onas_context *ctx, |
708 | 708 |
const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask) |
709 | 709 |
{ |
710 | 710 |
|
711 |
+ if (!(event->mask & IN_ISDIR)){ |
|
712 |
+ return; |
|
713 |
+ } |
|
714 |
+ |
|
715 |
+ if (optget(ctx->clamdopts, "OnAccessExtraScanning")->enabled) { |
|
716 |
+ logg("*ClamInotif: CREATE - adding %s to %s with wd:%d\n", child_path, path, wd); |
|
717 |
+ onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_DIR); |
|
718 |
+ } |
|
719 |
+ |
|
720 |
+ onas_ht_add_hierarchy(ddd_ht, child_path); |
|
721 |
+ onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask); |
|
722 |
+ |
|
723 |
+ return; |
|
724 |
+} |
|
725 |
+ |
|
726 |
+static void onas_ddd_handle_in_close_write(struct onas_context *ctx, const char *child_path) |
|
727 |
+{ |
|
711 | 728 |
struct stat s; |
712 | 729 |
|
713 | 730 |
if (optget(ctx->clamdopts, "OnAccessExtraScanning")->enabled) { |
714 | 731 |
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) { |
715 | 732 |
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_FILE); |
716 |
- |
|
717 |
- } else if (event->mask & IN_ISDIR) { |
|
718 |
- logg("*ClamInotif: CREATE - adding %s to %s with wd:%d\n", child_path, path, wd); |
|
719 |
- onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_DIR); |
|
720 |
- |
|
721 |
- onas_ht_add_hierarchy(ddd_ht, child_path); |
|
722 |
- onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask); |
|
723 | 733 |
} |
724 |
- } else { |
|
725 |
- if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
|
726 |
- if (!(event->mask & IN_ISDIR)) return; |
|
727 |
- |
|
728 |
- logg("*ClamInotif: MOVED_TO - adding %s to %s with wd:%d\n", child_path, path, wd); |
|
729 |
- onas_ht_add_hierarchy(ddd_ht, child_path); |
|
730 |
- onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask); |
|
731 | 734 |
} |
732 | 735 |
|
733 | 736 |
return; |