Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
Hi, On 01/06/2016 12:07 AM, Pathangi Janardhanan wrote: > Hi All, > > After trying a few things out, here are couple doubts that I have. > > 1. I am able to get this to work, if I modify the way the sendmsg is > being done, here is a temp. function that I wrote in my own service > to mimic the actions of sd_pid_notify_with_pids and with this I am able > to store the fds with systemd and reterive it back again on a > service restart. > > The only real difference is that I do a connect on the socket before > doing the sendmsg call, and searching through some stuff on google seems > to indicate that you need to do connect for unix domain sockets, but not > sure if that is the right thing to do? It's only necessary to connect() sockets that are in connection mode (SOCK_STREAM or SOCK_SEQPACKET), but this one is a SOCK_DGRAM socket. The reason why this is failing is because your systemd version is too old. All versions prior to v227 have a bug that causes a miscalculation of the msg_controllen value of the message header, hence the syscall rightfully fails. Any chance the Ubuntu people could backport a5bd3c32? Martin? As a workaround, you basically have to options: a) open-code the routine as you did, but you can leave off the connect() call, that's not needed. b) Pass your own PID to sd_pid_notify_with_fds(). > 2. The other issue I now have, is that after my service is restarted, I > am able to reterive this and continue to service the client. But I am > not able to delete this from the systemd state. > > The sequence is, > 1. Start the service, and handle some clients > 2. On a trigger, store the client fds > 3. Do a systemctl restart of the service, and the service gets these fds > in the new invocation This is intended. systemd holds a reference to the file descriptor you passed, so it will have it ready for you on each start of the service. This way, if the task just drops everything on idle, or even if it crashes, all fds that have been passed over earlier will be restored. > 4. it handles the client and the client closes the connection > 5. Now I do another restart of the service, but I still get this fd This shouldn't happen. If the client closes the connection, systemd should get EPOLLHUP on the fd and remove it from the set of file descriptors, hence dropping its reference. Are you sure the client properly closes its side of the communication? HTH, Daniel ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
Hi Daniel, >It's only necessary to connect() sockets that are in connection mode >(SOCK_STREAM or SOCK_SEQPACKET), but this one is a SOCK_DGRAM socket. >The reason why this is failing is because your systemd version is too >old. All versions prior to v227 have a bug that causes a miscalculation >of the msg_controllen value of the message header, hence the syscall >rightfully fails. Any chance the Ubuntu people could backport a5bd3c32? >Martin? >As a workaround, you basically have to options: >a) open-code the routine as you did, but you can leave off the connect()call, that's not needed. Yes, it works without the connect thank you. Maybe I will try to see if I can locally move to the latest version. >b) Pass your own PID to sd_pid_notify_with_fds() I had tried that before and it does not work, looks like even though my nfds is never zero, the have_pid flag is causing the issue, and to set that flag I have to pass a PID that is not my process PID? Thanks Jana ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
Hi, >> ret = sd_pid_notify_with_fds(0, 0, "FDSTORE=1\n", (const int *) fd, >>num_fd); > Is "fd" a single fd? If so you need to pass this as of course... No, fd is a int array, which holds num_fd, "fd" values. >The FDSTORE=1 line doesn't need to be suffixed with "\n" btw (but it >doesn't hurt if you do...) >It might be worth strace'ing your process to see that the right >sendmsg() call is issued. If in doubt, strace this specific code >snippet and paste the sendmsg() line here. This is the output of the strace call on this section of the code in the sd_pid_notify_with_fds, when I try to save the fds. socket(PF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 8 sendmsg(8, {msg_name(21)={sa_family=AF_LOCAL, sun_path="/run/systemd/notify"}, msg_iov(1)=[{"FDSTORE=1\n", 10}], msg_controllen=40, {cmsg_len=20, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, {7}}, msg_flags=0}, MSG_NOSIGNAL) = -1 EINVAL (Invalid argument) close(8)= 0 Thanks Jana ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
Hi, >> This is the output of the strace call on this section of the code in >> the sd_pid_notify_with_fds, when I try to save the fds. >> >> socket(PF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 8 >> >> sendmsg(8, {msg_name(21)={sa_family=AF_LOCAL, >> sun_path="/run/systemd/notify"}, msg_iov(1)=[{"FDSTORE=1\n", 10}], >> msg_controllen=40, {cmsg_len=20, cmsg_level=SOL_SOCKET, >> cmsg_type=SCM_RIGHTS, {7}}, msg_flags=0}, MSG_NOSIGNAL) = -1 EINVAL >> (Invalid argument) >Which version of systemd are you running? Does it contain a5bd3c32? Sorry forgot to attach the version, here is the version I am using jana@ctoserver11:~$ systemd --version systemd 225 +PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 +SECCOMP +BLKID -ELFUTILS +KMOD -IDN And my OS is Ubuntu Wily jana@ctoserver11:~$ lsb_release -a No LSB modules are available. Distributor ID:Ubuntu Description:Ubuntu 15.10 Release:15.10 Codename:wily let me if this is an issue and I have to move to another version? Thanks Jana ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
On 01/05/2016 06:33 PM, Pathangi Janardhanan wrote: > This is the output of the strace call on this section of the code in > the sd_pid_notify_with_fds, when I try to save the fds. > > socket(PF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 8 > > sendmsg(8, {msg_name(21)={sa_family=AF_LOCAL, > sun_path="/run/systemd/notify"}, msg_iov(1)=[{"FDSTORE=1\n", 10}], > msg_controllen=40, {cmsg_len=20, cmsg_level=SOL_SOCKET, > cmsg_type=SCM_RIGHTS, {7}}, msg_flags=0}, MSG_NOSIGNAL) = -1 EINVAL > (Invalid argument) Which version of systemd are you running? Does it contain a5bd3c32? Thanks, Daniel ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
On Tue, 05.01.16 01:11, Pathangi Janardhanan (path.j...@gmail.com) wrote: > Hi, > > I am using the function sd_pid_notify_with_fds and am unable to store the > fds with systemd. My service is a simple echo server, > and here is the snippet of code that is being called to store the FDS. I > have also included the debug code. > > // Store the FDs with systemd > e = getenv("NOTIFY_SOCKET"); > if (e == NULL) { > syslog(LOG_NOTICE, "environment variable Notify socket is null"); > } else { > syslog(LOG_NOTICE, "env. variable Notify Socket =%s %d", e, >strlen(e)); > } > > syslog(LOG_NOTICE, "Storing %d number of fds", num_fd); > ret = sd_pid_notify_with_fds(0, 0, "FDSTORE=1\n", (const int *) fd, >num_fd); Is "fd" a single fd? If so you need to pass this as of course... The FDSTORE=1 line doesn't need to be suffixed with "\n" btw (but it doesn't hurt if you do...) It might be worth strace'ing your process to see that the right sendmsg() call is issued. If in doubt, strace this specific code snippet and paste the sendmsg() line here. Lennart -- Lennart Poettering, Red Hat ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
Hi All, After trying a few things out, here are couple doubts that I have. 1. I am able to get this to work, if I modify the way the sendmsg is being done, here is a temp. function that I wrote in my own service to mimic the actions of sd_pid_notify_with_pids and with this I am able to store the fds with systemd and reterive it back again on a service restart. The only real difference is that I do a connect on the socket before doing the sendmsg call, and searching through some stuff on google seems to indicate that you need to do connect for unix domain sockets, but not sure if that is the right thing to do? Can someone point out what should be the correct fix for this to make it work? int my_pid_notify_with_fds(pid_t pid, int unset_environment, char *state, int *fds, unsigned n_fds) { struct sockaddr_un saddr; struct iovec iov; struct msghdr snd_msg; struct cmsghdr *cmsg; const char *e; int myfd, ret; saddr.sun_family = AF_UNIX; e = getenv("NOTIFY_SOCKET"); strncpy(saddr.sun_path, e,sizeof(saddr.sun_path)); myfd = socket(AF_UNIX, SOCK_DGRAM, 0); if (connect(myfd, (const struct sockaddr *) , sizeof(saddr)) != 0) { return -1; } iov.iov_base = (char *)state; iov.iov_len = strlen (state); snd_msg.msg_iov = snd_msg.msg_iovlen = 1; snd_msg.msg_name = NULL; snd_msg.msg_namelen = 0; snd_msg.msg_controllen = CMSG_SPACE(sizeof(int) * n_fds); snd_msg.msg_control = malloc(snd_msg.msg_controllen); cmsg = CMSG_FIRSTHDR(_msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int) * n_fds); memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * n_fds); ret = sendmsg(myfd, _msg, 0); close (myfd); return (ret); } 2. The other issue I now have, is that after my service is restarted, I am able to reterive this and continue to service the client. But I am not able to delete this from the systemd state. The sequence is, 1. Start the service, and handle some clients 2. On a trigger, store the client fds 3. Do a systemctl restart of the service, and the service gets these fds in the new invocation 4. it handles the client and the client closes the connection 5. Now I do another restart of the service, but I still get this fd So how do I make systemd "forgot" the fd or how is this scenario to be handled? Thanks jana On Tue, Jan 5, 2016 at 1:55 PM, Pathangi Janardhananwrote: > Hi, > > > >> This is the output of the strace call on this section of the code in > >> the sd_pid_notify_with_fds, when I try to save the fds. > >> > >> socket(PF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 8 > >> > >> sendmsg(8, {msg_name(21)={sa_family=AF_LOCAL, > >> sun_path="/run/systemd/notify"}, msg_iov(1)=[{"FDSTORE=1\n", 10}], > >> msg_controllen=40, {cmsg_len=20, cmsg_level=SOL_SOCKET, > >> cmsg_type=SCM_RIGHTS, {7}}, msg_flags=0}, MSG_NOSIGNAL) = -1 EINVAL > >> (Invalid argument) > > >Which version of systemd are you running? Does it contain a5bd3c32? > > Sorry forgot to attach the version, here is the version I am using > > jana@ctoserver11:~$ systemd --version > systemd 225 > +PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP > +GCRYPT +GNUTLS +ACL +XZ -LZ4 +SECCOMP +BLKID -ELFUTILS +KMOD -IDN > > And my OS is Ubuntu Wily > > jana@ctoserver11:~$ lsb_release -a > No LSB modules are available. > Distributor ID:Ubuntu > Description:Ubuntu 15.10 > Release:15.10 > Codename:wily > > let me if this is an issue and I have to move to another version? > > Thanks > Jana > > ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
05.01.2016, 09:11, "Pathangi Janardhanan":Hi, I am using the function sd_pid_notify_with_fds and am unable to store the fds with systemd. My service is a simple echo server, and here is the snippet of code that is being called to store the FDS. I have also included the debug code. // Store the FDs with systemd e = getenv("NOTIFY_SOCKET"); if (e == NULL) { syslog(LOG_NOTICE, "environment variable Notify socket is null"); } else { syslog(LOG_NOTICE, "env. variable Notify Socket =%s %d", e, strlen(e)); } syslog(LOG_NOTICE, "Storing %d number of fds", num_fd); ret = sd_pid_notify_with_fds(0, 0, "FDSTORE=1\n", (const int *) fd, num_fd); syslog(LOG_NOTICE, "Result of sd notify %d", ret); From the debug printf I seeJan 5 00:37:23 ctoserver11 /usr/bin/myechoser[13640]: env. variable Notify Socket =/run/systemd/notify 19Jan 5 00:37:23 ctoserver11 /usr/bin/myechoser[13640]: Storing 1 number of fdsJan 5 00:37:23 ctoserver11 /usr/bin/myechoser[13640]: Result of sd notify -22 The return value seems to be -EINVAL, but looking at the code and the above debug, I am not sure why this is happening? Any help would be great.ThanksJana ,___systemd-devel mailing listsystemd-devel@lists.freedesktop.orghttp://lists.freedesktop.org/mailman/listinfo/systemd-devel Which version of systemd are you using? See https://github.com/systemd/systemd/commit/a5bd3c32abb00ad945282568fd1a97c180b68047That bug affects `systemtctl restart systemd-journald`.See https://github.com/systemd/systemd/issues/2236#issuecomment-167739937 --Best regards,Evgeny Vereshchagin ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] Unable to store fds with systemd and reterive it back again
On Tue, Jan 05, 2016 at 01:11:16AM -0500, Pathangi Janardhanan wrote: > Hi, > > I am using the function sd_pid_notify_with_fds and am unable to store the > fds with systemd. My service is a simple echo server, > and here is the snippet of code that is being called to store the FDS. I > have also included the debug code. > > // Store the FDs with systemd > e = getenv("NOTIFY_SOCKET"); > if (e == NULL) { > syslog(LOG_NOTICE, "environment variable Notify socket is null"); > } else { > syslog(LOG_NOTICE, "env. variable Notify Socket =%s %d", e, >strlen(e)); > } > > syslog(LOG_NOTICE, "Storing %d number of fds", num_fd); > ret = sd_pid_notify_with_fds(0, 0, "FDSTORE=1\n", (const int *) fd, >num_fd); > syslog(LOG_NOTICE, "Result of sd notify %d", ret); > > From the debug printf I see > Jan 5 00:37:23 ctoserver11 /usr/bin/myechoser[13640]: env. variable Notify > Socket =/run/systemd/notify 19 > Jan 5 00:37:23 ctoserver11 /usr/bin/myechoser[13640]: Storing 1 number of > fds > Jan 5 00:37:23 ctoserver11 /usr/bin/myechoser[13640]: Result of sd notify > -22 > > > The return value seems to be -EINVAL, but looking at the code and the > above debug, I am not sure why this is happening? > > Any help would be great. You need to set FileDescriptorStoreMax= to nonzero value in your service's unit file. See man systemd.service -- Tomasz TorczThere exists no separation between gods and men: xmpp: zdzich...@chrome.pl one blends softly casual into the other. ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel