From owner-freebsd-questions@freebsd.org Tue Jun 15 23:30:06 2021 Return-Path: Delivered-To: freebsd-questions@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 76C9F656049 for ; Tue, 15 Jun 2021 23:30:06 +0000 (UTC) (envelope-from kh@panix.com) Received: from mailbackend.panix.com (mailbackend.panix.com [166.84.1.89]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4G4PgK0WkKz3pkm for ; Tue, 15 Jun 2021 23:30:04 +0000 (UTC) (envelope-from kh@panix.com) Received: from rain.home (pool-96-230-243-2.bstnma.fios.verizon.net [96.230.243.2]) by mailbackend.panix.com (Postfix) with ESMTPSA id 4G4PgG70cMz42ZL for ; Tue, 15 Jun 2021 19:30:02 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=panix.com; s=panix; t=1623799803; bh=/Wh2uLJ3DRWYfUi9DOAFiLhBPOcHx+4ZuSnB7+tnHi4=; h=Subject:To:References:From:Date:In-Reply-To; b=R0dAyR7Qk+kugkfyVYnT4i9xS98I0v8kT9y/SyUkbaZC5uvhTH0Bs1DwFVc3TboRu YybgY2IjxN///UYNRJUeK013FNOLPIO/vyRtUGWvSm9ZtGfATAIS4pnjYxR1xpOyRR wvehonb+JmSgGrMP9iGgZnHtBfwuoh1RKged4DAk= Subject: Re: Is a successful call to write(2) atomic? To: freebsd-questions@freebsd.org References: <25718.1623792483@segfault.tristatelogic.com> From: Kurt Hackenberg Message-ID: Date: Tue, 15 Jun 2021 19:29:59 -0400 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:78.0) Gecko/20100101 Thunderbird/78.6.0 MIME-Version: 1.0 In-Reply-To: <25718.1623792483@segfault.tristatelogic.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: 4G4PgK0WkKz3pkm X-Spamd-Bar: ---- Authentication-Results: mx1.freebsd.org; dkim=pass header.d=panix.com header.s=panix header.b=R0dAyR7Q; dmarc=none; spf=pass (mx1.freebsd.org: domain of kh@panix.com designates 166.84.1.89 as permitted sender) smtp.mailfrom=kh@panix.com X-Spamd-Result: default: False [-4.20 / 15.00]; RCVD_VIA_SMTP_AUTH(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[166.84.1.89:from]; R_SPF_ALLOW(-0.20)[+ip4:166.84.0.0/16]; TO_DN_NONE(0.00)[]; RCVD_DKIM_ARC_DNSWL_MED(-0.50)[]; DKIM_TRACE(0.00)[panix.com:+]; RCVD_IN_DNSWL_MED(-0.20)[166.84.1.89:from]; NEURAL_HAM_SHORT(-1.00)[-1.000]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; SUBJECT_ENDS_QUESTION(1.00)[]; ASN(0.00)[asn:2033, ipnet:166.84.0.0/16, country:US]; MID_RHS_MATCH_FROM(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[96.230.243.2:received]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; R_DKIM_ALLOW(-0.20)[panix.com:s=panix]; FROM_HAS_DN(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; MIME_GOOD(-0.10)[text/plain]; PREVIOUSLY_DELIVERED(0.00)[freebsd-questions@freebsd.org]; DMARC_NA(0.00)[panix.com]; RCPT_COUNT_ONE(0.00)[1]; DWL_DNSWL_LOW(-1.00)[panix.com:dkim]; RCVD_COUNT_TWO(0.00)[2]; RCVD_TLS_ALL(0.00)[]; MAILMAN_DEST(0.00)[freebsd-questions] X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jun 2021 23:30:06 -0000 On 2021/06/15 17:28, Ronald F. Guilmette wrote: >> There are two common solutions. Paul suggested one of them: serialize >> access through a single process. > > I stated in response that I was 100% sure that that would solve the problem. > Upon further reflection however, I wish to withdraw that assertion. > > In fact, it now appear to me that the notion of using a pipe to pass > (indivisible?) lines of data up to a parent/controller process from a > number of child processes, and then allowing that parent to "sequentialize" > those data lines onto disk actually just moves the problem around, without > actually addressing it. > > Consider this: If single ("successful") call to write() (which returns a > value indicating that all bytes were written) fails to guarantee that > the entire written buffer will be treated as an indivisible unit, then > it likely fails to provide that fundamental guarantee *regardless* of > whether the specific file descriptor being written to is associated > with either (a) a file on the local hard disk or (b) a pipe being used > to communicate with a another process. You're right. Sorry, I didn't give enough attention to the details of that solution. But it works by just changing the messaging mechanism a little: Have many pipes, one for each sender, all sending to the single write process, which uses the system call select() to wait for activity on any of them. The write process still has to make sure it reads all of a message from a pipe before going on to another pipe, but that's straightforward, if it knows how much data to expect. Did you mentions lines -- each sender sends one line to be written, and each line must be atomic, but it's OK to write the many lines in any order? If so, the writer process just keeps reading a pipe until it gets a complete line. If it's not lines, then do something similar -- have an end-of-message marker, or precede each message with its length in bytes, or hard-code a fixed length for all messages -- any way for the writer process to know it has a complete message.