[stgt] tgtadm/tgtd management issue: buffer size truncated sometimes
Artyom Pervukhin
artyom at evasive.ru
Mon Jan 27 17:12:20 CET 2014
On 27 Jan 2014, at 19:42, FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp> wrote:
> Hi,
>
> On Mon, 27 Jan 2014 18:44:42 +0400
> Artyom Pervukhin <artyom at evasive.ru> wrote:
>
>> I've done some additional stracing on the tgtd's side this time, please see below:
>>
>> Testing 300 targets:
>>
>> command:
>>
>> root at sandbox:~ # tgtadm -C 0 --op show --mode target
>>
>> (command shows full output)
>>
>> tgtd writes:
>>
>> write(10, "\0\0\0\0\305\325\4\0", 8) = 8
>> write(10, "Target 1: iqn.2014-01:d1\n Sys"..., 316861) = 224000
>> write(10, " State: ready\n I_T nexu"..., 92861) = 92861
>>
>> command:
>>
>> root at sandbox:~ # tgtadm -C 0 --op show --mode target | wc -c
>> 316860
>>
>> tgtd writes stays the same as above.
>>
>>
>>
>> Testing 900 targets:
>>
>> root at sandbox:~ # tgtadm -C 0 --op show --mode target
>>
>> (command shows incomplete output)
>>
>> tgtd writes:
>>
>> write(10, "\0\0\0\0u\205\16\0", 8) = 8
>> write(10, "Target 1: iqn.2014-01:d1\n Sys"..., 951661) = 256000
>> write(10, "a: No\n Prevent remova"..., 695661) = 176000
>> write(10, " Removable media: No\n "..., 519661) = 176000
>> write(10, "T nexus information:\n LUN inf"..., 343661) = 176000
>> write(10, " Backing store path: None\n "..., 167661) = 167661
>>
>> command:
>>
>> root at sandbox:~ # tgtadm -C 0 --op show --mode target | wc -c
>> 929621
>>
>> tgtd writes:
>>
>> write(10, "\0\0\0\0u\205\16\0", 8) = 8
>> write(10, "Target 1: iqn.2014-01:d1\n Sys"..., 951661) = 944000
>> write(10, "t removal: No\n Readon"..., 7661) = -1 EPIPE (Broken pipe)
>> --- SIGPIPE (Broken pipe) @ 0 (0) ---
>>
>>
>>
>> Seeing this, I assumed the bug is on tgtadm's side.
>
> Thanks a lot for the investigation. The following fixes the problem?
>
> Note that tgtd uses a stream to store what tgtd sends to tgtadm. The
> buffer of the stream is managed glibc (internally allocated via
> malloc). That's a limit about how many targets you can see via tgtadm.
>
>
> diff --git a/usr/tgtadm.c b/usr/tgtadm.c
> index cc63fbf..8e0d5dd 100644
> --- a/usr/tgtadm.c
> +++ b/usr/tgtadm.c
> @@ -234,7 +234,8 @@ static int ipc_mgmt_connect(int *fd)
> static int ipc_mgmt_rsp(int fd, struct tgtadm_req *req)
> {
> struct tgtadm_rsp rsp;
> - int err, rest, len;
> + int err, len, done;
> + char *buf;
>
> retry:
> err = recv(fd, &rsp, sizeof(rsp), MSG_WAITALL);
> @@ -278,23 +279,28 @@ retry:
> }
> }
>
> - rest = rsp.len - sizeof(rsp);
> - if (!rest)
> + len = rsp.len - sizeof(rsp);
> + if (!len)
> return 0;
>
> - while (rest) {
> - char buf[BUFSIZE];
> - memset(buf, 0, sizeof(buf));
> - len = min_t(int, sizeof(buf) - 1, rest);
> - err = read(fd, buf, len);
> - if (err <= 0) {
> - eprintf("\ncan't get the full response, %m\n");
> - return errno;
> + buf = malloc(len);
> + done = 0;
> + while (len > done) {
> + int ret;
> + ret = read(fd, buf + done, len - done);
> + if (ret < 0) {
> + if (errno == EAGAIN)
> + continue;
> + fprintf(stderr, "failed to read from tgtd, %d", errno);
> + break;
> }
> - fputs(buf, stdout);
> - rest -= len;
> + done += ret;
> }
>
> + if (done == len)
> + fputs(buf, stdout);
> + free(buf);
> +
> return 0;
> }
>
I’ve just applied this patch and the problem is gone: all tests I’ve used before are passing.
Thanks a lot!--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list