Re: [systemd-devel] question about system reboot and shutdown

2017-08-09 Thread Tilman Baumann
On 09.08.2017 11:28, Tilman Baumann wrote:
> DL;DR
> UPS shutdowns are tricky. Clean file-systems are not the only concern.
> But if you can make assumptions about your storage backend you might be
> able to cut corners safely.
> 
> In my experience, the only place where you can hook in a non racy way is
> in the kernel.
> 
> https://unix.stackexchange.com/questions/122557/how-does-the-system-shutdown-of-a-linux-kernel-work-internally

Apologies, I copy and pasted the wrong link
https://stackoverflow.com/questions/5938325/how-do-i-detect-reboot-shutdown-from-a-linux-driver

The magic is here IIRC
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/kernel/reboot.c
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] question about system reboot and shutdown

2017-08-09 Thread Tilman Baumann
DL;DR
UPS shutdowns are tricky. Clean file-systems are not the only concern.
But if you can make assumptions about your storage backend you might be
able to cut corners safely.

In my experience, the only place where you can hook in a non racy way is
in the kernel.

https://unix.stackexchange.com/questions/122557/how-does-the-system-shutdown-of-a-linux-kernel-work-internally

Because this is the hook which a lot of RAID systems and storage
back-ends use to signal a clean poweroff.
If you just halt your system very late in shutdown in userspace and
switch the lights off, the kernel will never run this code.
The result is that for example RAID unclean flags are still set.

UPS kernel drivers generally solve this problem by setting a 'powerfail'
flag before they initiate a shutdown.
The driver is hooked in the shutdown notifier and initiates the poweroff
through the UPS.

Another race condition is, that during the shutdown, the power could
have come back. THE UPS needs to recognize that and still power off the
system to ensure a reboot and then switch it back on.

But I think in your case, using a time based approach is quite valid.
Late in shutdown, set the powerfail flag in the UPS and set a poweroff
timer. While that timer is ticking in the UPS, your system will continue
shutting down safely and halt. And when the timer ran out the UPS will
switch the lights off.
That is by nature racy. But in a well defined system I suppose the risk
is manageable.


Mind you, my exposure tho this stuff is 10 years old or so. A lot might
have happened since then.
Back then I was fighting with a APC UPS which did not support timer
based poweroff and in combination with a 3ware RAID controller lead to
degraded volumes after powerfail.
The shutdown was done in userspace and the UPS did not know timer based
shutdowns. Hence the kernel hook never ran.

BTW. if you don't want to reinvent the wheel. networkupstools (NUT) was
back then the only really sensible software stack that did in practice
most things right.
As I said. My experience is 10 years dated. And I don't know if NUT
works well with systemd. And of course a network based system is
overkill. But perhaps you can have a look at it for some 'best practices'


On 09.08.2017 11:02, Marek Floriańczyk wrote:
> Dnia środa, 9 sierpnia 2017 10:29:37 CEST Lennart Poettering pisze:
>> On Di, 08.08.17 16:03, Marek Floriańczyk (marek.florianc...@gmail.com) wrote:
>>> Hi all,
>>>
>>> I have a small device MicroUPS which helps me to shutdown my system on
>>> embedded devices, it is controlled by script /etc/init.d/microups and in
>>> this script I need to know whether system is going down for reboot or for
>>> halt, because in case of halt I need to send small data over RS232 to
>>> MicroUPS device to cut the power off.
>>
>> Note that this is necessarily racy: you can't really know how long the
>> system will actually take to shut down, hence if you trigger your
>> hardware for shutdown at an early phase of the shutdown process you
>> now start racing the remaining shutdown phase against the hardware turning
>> off power...
>>
>> If you want to fix this properly, and remove this race entirely the
>> only fully correct way out I see is to use an initrd for booting, and
>> doing the RS232 thing from that. Note that if you use a properly
>> prepared initrd, systemd will actually transition back to it at
>> shutdown, and while doing so it will permit unmounting the root file
>> system properly at shutdown. And only if you start the RS232 thing
>> after the point where the root fs is unmounted you can fully remove
>> the race in the generic case, since only at that point everything is
>> fully synced to disk, all complex storage is disassembled and so on.
>>
>> Now, adding this to the initrd is not the easiest thing in the world,
>> and in particular in embedded devices avoiding an initrd might be a
>> good thing. As long as you have no complex storage (i.e. no DM, no
>> LVM, no LUKS, no RAID, no iscsi, yaddayadda) you can instead cut a
>> corner and just drop in a shutdown script to
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] sd-bus example code for SetLinkDNS()

2017-07-25 Thread Tilman Baumann
Little follow-up question. What would you say is best practice for a vpn
client?

- Add commandline option --update-systemd-resolved or so
- Autodetect existence of the interface and just do it? (How?)
- Always try to do the update but silently ignore if it fails and fall
back to updating resolve.conf instead?

I was going with the commandline option. But I'm beginning to hate it.
Do the right thing if you know what's right rings better with me.

I will have to introduce a option for domain filter (and search domain)
anyway, that stuff will never work out of the box.
The VPN protocol is one of those nasty ppp over ssl jobs. And the only
fields passed down to the client are the nameservers.

Cheers
 Tilman

On 21.07.2017 14:35, Lennart Poettering wrote:
> On Wed, 19.07.17 11:20, Tilman Baumann (til...@baumann.name) wrote:
> 
>> Hi folks,
>>
>> I'm trying to teach a vpn software (openfortivpn) how to properly set up
>> DNS in a systemd-resolve environment.
>>
>> I'm trying to set up a equivalent to this in C.
>> busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1
>> org.freedesktop.resolve1.Manager SetLinkDNS 'ia(iay)' 16 2 2 4 10 10 10
>> 10 2 4 10 10 10 11
>> [https://gist.github.com/tbaumann/d484efb2e27613654a52dbe11cfe53b8]
>>
>> I came up with this quick proof of concept code based on the example
>> code in the sd-bus docu.
>> Of course it segfaults. No surprise, I have done nothing to hint at the
>> length of the inner byte array. (ay)
>>
>> I was unable to find any example code that would give me a hint on how
>> to pass such more complex data structures into sd_bus_call_method()
>>
>> int SetLinkDNSv4(sd_bus *bus, int if_index, struct in_addr ns1, struct
>> in_addr ns2) {
>>   sd_bus_error error = SD_BUS_ERROR_NULL;
>>   sd_bus_message *m = NULL;
>>   int r;
>>   struct dns_address {
>> int sin_family;
>> struct in_addr ip_addr;
>>   };
>>   struct dns_address addresses[2];
>>
>>
>>   addresses[0].sin_family = AF_INET;
>>   addresses[0].ip_addr = ns1;
>>   addresses[1].sin_family = AF_INET;
>>   addresses[1].ip_addr = ns2;
>>
>>   r = sd_bus_call_method(bus,
>>  "org.freedesktop.resolve1",   /*
>> service to contact */
>>  "/org/freedesktop/resolve1",  /* object
>> path */
>>  "org.freedesktop.resolve1.Manager",   /*
>> interface name */
>>  "SetLinkDNS", /* method
>> name */
>>  ,   /* object
>> to return error in */
>>  ,   /* return
>> message on success */
>>  "ia(iay)",/* input
>> signature */
>>  if_index,
>>  2,/* Array
>> size */
>>  addresses);
>> }
>>
>> [Full code:
>> https://gist.github.com/tbaumann/0f466c984c858767c966458d53483697]
>>
>> My guess is that I can have it easier if I somehow use
>> sd_bus_message_append() to assemble the message. But I don't see a clear
>> path either.
> 
> You have to do something like this:
> 
> sd_bus_message_new_method(..., );
> sd_bus_message_append(m, "i", ifindex);
> sd_bus_message_open_container(m, 'a', '(iay)');
> for (i = 0; i < n_addresses; i++) {
> sd_bus_message_open_container(m, '(', "iay"));
> sd_bus_message_append(m, "i", addresses[i].sin_family);
> sd_bus_message_append_array(m, 'y', [i].ip_addr, 
> sizeof(addresses[i].ip_addr));
> sd_bus_message_close_container(m);
> }
> sd_bus_message_close_container(m);
> sd_bus_message_send(..., m);
> sd_bus_message_unref(m);
> 
> (not tested, just written down from the top of my head, and of course,
> don't forget to add proper error checking)
> 
> Lennart
> 
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] sd-bus example code for SetLinkDNS()

2017-07-21 Thread Tilman Baumann
On 21.07.2017 14:44, Tilman Baumann wrote:
> On 21.07.2017 14:35, Lennart Poettering wrote:
>> On Wed, 19.07.17 11:20, Tilman Baumann (til...@baumann.name) wrote:
>>
>  >> My guess is that I can have it easier if I somehow use
>>> sd_bus_message_append() to assemble the message. But I don't see a clear
>>> path either.
>>
>> You have to do something like this:
>>
>> sd_bus_message_new_method(..., );
>> sd_bus_message_append(m, "i", ifindex);
>> sd_bus_message_open_container(m, 'a', '(iay)');
>> for (i = 0; i < n_addresses; i++) {
>> sd_bus_message_open_container(m, '(', "iay"));
>> sd_bus_message_append(m, "i", addresses[i].sin_family);
>> sd_bus_message_append_array(m, 'y', [i].ip_addr, 
>> sizeof(addresses[i].ip_addr));
>> sd_bus_message_close_container(m);
>> }
>> sd_bus_message_close_container(m);
>> sd_bus_message_send(..., m);
>> sd_bus_message_unref(m);

And here the working solution for the permanent record.
r = sd_bus_message_new_method_call(
  bus, ,
  "org.freedesktop.resolve1",
  "/org/freedesktop/resolve1",
  "org.freedesktop.resolve1.Manager",
  "SetLinkDNS");
r = sd_bus_message_append(m, "i", if_index);
r = sd_bus_message_open_container(m, 'a', "(iay)");
for (int i = 0; i < addresses_size; i++) {
fprintf(stderr, "server %d\n", i);
r = sd_bus_message_open_container(m, 'r', "iay");
r = sd_bus_message_append(m, "i", addresses[i].sin_family);
r = sd_bus_message_append_array(m, 'y', [i].ip_addr,
sizeof(addresses[i].ip_addr));
r = sd_bus_message_close_container(m);
}
r = sd_bus_message_close_container(m);
r = sd_bus_call(bus, m, 0, , );
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] sd-bus example code for SetLinkDNS()

2017-07-21 Thread Tilman Baumann
On 21.07.2017 14:35, Lennart Poettering wrote:
> On Wed, 19.07.17 11:20, Tilman Baumann (til...@baumann.name) wrote:
> 
 >> My guess is that I can have it easier if I somehow use
>> sd_bus_message_append() to assemble the message. But I don't see a clear
>> path either.
> 
> You have to do something like this:
> 
> sd_bus_message_new_method(..., );
> sd_bus_message_append(m, "i", ifindex);
> sd_bus_message_open_container(m, 'a', '(iay)');
> for (i = 0; i < n_addresses; i++) {
> sd_bus_message_open_container(m, '(', "iay"));
> sd_bus_message_append(m, "i", addresses[i].sin_family);
> sd_bus_message_append_array(m, 'y', [i].ip_addr, 
> sizeof(addresses[i].ip_addr));
> sd_bus_message_close_container(m);
> }
> sd_bus_message_close_container(m);
> sd_bus_message_send(..., m);
> sd_bus_message_unref(m);
> 
> (not tested, just written down from the top of my head, and of course,
> don't forget to add proper error checking)

Phantastic, thanks Lennart
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] sd-bus example code for SetLinkDNS()

2017-07-21 Thread Tilman Baumann
Any hint?

I would be happy to just see some similar code that deals with arrays of
complex structures. If I see a example that is similar, I'm sure I can
learn from it.
So if anybody knows of a code example that does that...

Thanks

On 19.07.2017 11:20, Tilman Baumann wrote:
> Hi folks,
> 
> I'm trying to teach a vpn software (openfortivpn) how to properly set up
> DNS in a systemd-resolve environment.
> 
> I'm trying to set up a equivalent to this in C.
> busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1
> org.freedesktop.resolve1.Manager SetLinkDNS 'ia(iay)' 16 2 2 4 10 10 10
> 10 2 4 10 10 10 11
> [https://gist.github.com/tbaumann/d484efb2e27613654a52dbe11cfe53b8]
> 
> I came up with this quick proof of concept code based on the example
> code in the sd-bus docu.
> Of course it segfaults. No surprise, I have done nothing to hint at the
> length of the inner byte array. (ay)
> 
> I was unable to find any example code that would give me a hint on how
> to pass such more complex data structures into sd_bus_call_method()
> 
> int SetLinkDNSv4(sd_bus *bus, int if_index, struct in_addr ns1, struct
> in_addr ns2) {
>   sd_bus_error error = SD_BUS_ERROR_NULL;
>   sd_bus_message *m = NULL;
>   int r;
>   struct dns_address {
> int sin_family;
> struct in_addr ip_addr;
>   };
>   struct dns_address addresses[2];
> 
> 
>   addresses[0].sin_family = AF_INET;
>   addresses[0].ip_addr = ns1;
>   addresses[1].sin_family = AF_INET;
>   addresses[1].ip_addr = ns2;
> 
>   r = sd_bus_call_method(bus,
>  "org.freedesktop.resolve1",   /*
> service to contact */
>  "/org/freedesktop/resolve1",  /* object
> path */
>  "org.freedesktop.resolve1.Manager",   /*
> interface name */
>  "SetLinkDNS", /* method
> name */
>  ,   /* object
> to return error in */
>  ,   /* return
> message on success */
>  "ia(iay)",/* input
> signature */
>  if_index,
>  2,/* Array
> size */
>  addresses);
> }
> 
> [Full code:
> https://gist.github.com/tbaumann/0f466c984c858767c966458d53483697]
> 
> My guess is that I can have it easier if I somehow use
> sd_bus_message_append() to assemble the message. But I don't see a clear
> path either.
> 
> Also, the length of the array can be one or two. So that bit is variable
> too.
> 
> Thanks for any hints
>  Tilman Baumann
> ___
> systemd-devel mailing list
> systemd-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel
> 
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] sd-bus example code for SetLinkDNS()

2017-07-19 Thread Tilman Baumann
Hi folks,

I'm trying to teach a vpn software (openfortivpn) how to properly set up
DNS in a systemd-resolve environment.

I'm trying to set up a equivalent to this in C.
busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1
org.freedesktop.resolve1.Manager SetLinkDNS 'ia(iay)' 16 2 2 4 10 10 10
10 2 4 10 10 10 11
[https://gist.github.com/tbaumann/d484efb2e27613654a52dbe11cfe53b8]

I came up with this quick proof of concept code based on the example
code in the sd-bus docu.
Of course it segfaults. No surprise, I have done nothing to hint at the
length of the inner byte array. (ay)

I was unable to find any example code that would give me a hint on how
to pass such more complex data structures into sd_bus_call_method()

int SetLinkDNSv4(sd_bus *bus, int if_index, struct in_addr ns1, struct
in_addr ns2) {
  sd_bus_error error = SD_BUS_ERROR_NULL;
  sd_bus_message *m = NULL;
  int r;
  struct dns_address {
int sin_family;
struct in_addr ip_addr;
  };
  struct dns_address addresses[2];


  addresses[0].sin_family = AF_INET;
  addresses[0].ip_addr = ns1;
  addresses[1].sin_family = AF_INET;
  addresses[1].ip_addr = ns2;

  r = sd_bus_call_method(bus,
 "org.freedesktop.resolve1",   /*
service to contact */
 "/org/freedesktop/resolve1",  /* object
path */
 "org.freedesktop.resolve1.Manager",   /*
interface name */
 "SetLinkDNS", /* method
name */
 ,   /* object
to return error in */
 ,   /* return
message on success */
 "ia(iay)",/* input
signature */
 if_index,
 2,/* Array
size */
 addresses);
}

[Full code:
https://gist.github.com/tbaumann/0f466c984c858767c966458d53483697]

My guess is that I can have it easier if I somehow use
sd_bus_message_append() to assemble the message. But I don't see a clear
path either.

Also, the length of the array can be one or two. So that bit is variable
too.

Thanks for any hints
 Tilman Baumann
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel