Deleted Added
full compact
primary.c (210881) primary.c (210886)
1/*-
2 * Copyright (c) 2009 The FreeBSD Foundation
1/*-
2 * Copyright (c) 2009 The FreeBSD Foundation
3 * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3 * All rights reserved.
4 *
5 * This software was developed by Pawel Jakub Dawidek under sponsorship from
6 * the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 12 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
4 * All rights reserved.
5 *
6 * This software was developed by Pawel Jakub Dawidek under sponsorship from
7 * the FreeBSD Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:

--- 12 unchanged lines hidden (view full) ---

24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sbin/hastd/primary.c 210881 2010-08-05 19:01:57Z pjd $");
32__FBSDID("$FreeBSD: head/sbin/hastd/primary.c 210886 2010-08-05 19:16:31Z pjd $");
32
33#include <sys/types.h>
34#include <sys/time.h>
35#include <sys/bio.h>
36#include <sys/disk.h>
37#include <sys/refcount.h>
38#include <sys/stat.h>
39

--- 20 unchanged lines hidden (view full) ---

60#include "hast_proto.h"
61#include "hastd.h"
62#include "metadata.h"
63#include "proto.h"
64#include "pjdlog.h"
65#include "subr.h"
66#include "synch.h"
67
33
34#include <sys/types.h>
35#include <sys/time.h>
36#include <sys/bio.h>
37#include <sys/disk.h>
38#include <sys/refcount.h>
39#include <sys/stat.h>
40

--- 20 unchanged lines hidden (view full) ---

61#include "hast_proto.h"
62#include "hastd.h"
63#include "metadata.h"
64#include "proto.h"
65#include "pjdlog.h"
66#include "subr.h"
67#include "synch.h"
68
69/* The is only one remote component for now. */
70#define ISREMOTE(no) ((no) == 1)
71
68struct hio {
69 /*
70 * Number of components we are still waiting for.
71 * When this field goes to 0, we can send the request back to the
72 * kernel. Each component has to decrease this counter by one
73 * even on failure.
74 */
75 unsigned int hio_countdown;

--- 343 unchanged lines hidden (view full) ---

419 TAILQ_INSERT_HEAD(&hio_free_list, hio, hio_free_next);
420 }
421
422 /*
423 * Turn on signals handling.
424 */
425 signal(SIGINT, sighandler);
426 signal(SIGTERM, sighandler);
72struct hio {
73 /*
74 * Number of components we are still waiting for.
75 * When this field goes to 0, we can send the request back to the
76 * kernel. Each component has to decrease this counter by one
77 * even on failure.
78 */
79 unsigned int hio_countdown;

--- 343 unchanged lines hidden (view full) ---

423 TAILQ_INSERT_HEAD(&hio_free_list, hio, hio_free_next);
424 }
425
426 /*
427 * Turn on signals handling.
428 */
429 signal(SIGINT, sighandler);
430 signal(SIGTERM, sighandler);
431 signal(SIGHUP, sighandler);
427}
428
429static void
430init_local(struct hast_resource *res)
431{
432 unsigned char *buf;
433 size_t mapsize;
434

--- 1273 unchanged lines hidden (view full) ---

1708{
1709 bool unlock;
1710
1711 switch (sig) {
1712 case SIGINT:
1713 case SIGTERM:
1714 sigexit_received = true;
1715 break;
432}
433
434static void
435init_local(struct hast_resource *res)
436{
437 unsigned char *buf;
438 size_t mapsize;
439

--- 1273 unchanged lines hidden (view full) ---

1713{
1714 bool unlock;
1715
1716 switch (sig) {
1717 case SIGINT:
1718 case SIGTERM:
1719 sigexit_received = true;
1720 break;
1721 case SIGHUP:
1722 sighup_received = true;
1723 break;
1716 default:
1717 assert(!"invalid condition");
1718 }
1719 /*
1720 * XXX: Racy, but if we cannot obtain hio_guard_lock here, we don't
1721 * want to risk deadlock.
1722 */
1723 unlock = mtx_trylock(&hio_guard_lock);
1724 cv_signal(&hio_guard_cond);
1725 if (unlock)
1726 mtx_unlock(&hio_guard_lock);
1727}
1728
1724 default:
1725 assert(!"invalid condition");
1726 }
1727 /*
1728 * XXX: Racy, but if we cannot obtain hio_guard_lock here, we don't
1729 * want to risk deadlock.
1730 */
1731 unlock = mtx_trylock(&hio_guard_lock);
1732 cv_signal(&hio_guard_cond);
1733 if (unlock)
1734 mtx_unlock(&hio_guard_lock);
1735}
1736
1737static void
1738config_reload(void)
1739{
1740 struct hastd_config *newcfg;
1741 struct hast_resource *res;
1742 unsigned int ii, ncomps;
1743 int modified;
1744
1745 pjdlog_info("Reloading configuration...");
1746
1747 ncomps = HAST_NCOMPONENTS;
1748
1749 newcfg = yy_config_parse(cfgpath, false);
1750 if (newcfg == NULL)
1751 goto failed;
1752
1753 TAILQ_FOREACH(res, &newcfg->hc_resources, hr_next) {
1754 if (strcmp(res->hr_name, gres->hr_name) == 0)
1755 break;
1756 }
1757 /*
1758 * If resource was removed from the configuration file, resource
1759 * name, provider name or path to local component was modified we
1760 * shouldn't be here. This means that someone modified configuration
1761 * file and send SIGHUP to us instead of main hastd process.
1762 * Log advice and ignore the signal.
1763 */
1764 if (res == NULL || strcmp(gres->hr_name, res->hr_name) != 0 ||
1765 strcmp(gres->hr_provname, res->hr_provname) != 0 ||
1766 strcmp(gres->hr_localpath, res->hr_localpath) != 0) {
1767 pjdlog_warning("To reload configuration send SIGHUP to the main hastd process (pid %u).",
1768 (unsigned int)getppid());
1769 goto failed;
1770 }
1771
1772#define MODIFIED_REMOTEADDR 0x1
1773#define MODIFIED_REPLICATION 0x2
1774#define MODIFIED_TIMEOUT 0x4
1775 modified = 0;
1776 if (strcmp(gres->hr_remoteaddr, res->hr_remoteaddr) != 0) {
1777 /*
1778 * Don't copy res->hr_remoteaddr to gres just yet.
1779 * We want remote_close() to log disconnect from the old
1780 * addresses, not from the new ones.
1781 */
1782 modified |= MODIFIED_REMOTEADDR;
1783 }
1784 if (gres->hr_replication != res->hr_replication) {
1785 gres->hr_replication = res->hr_replication;
1786 modified |= MODIFIED_REPLICATION;
1787 }
1788 if (gres->hr_timeout != res->hr_timeout) {
1789 gres->hr_timeout = res->hr_timeout;
1790 modified |= MODIFIED_TIMEOUT;
1791 }
1792 /*
1793 * If only timeout was modified we only need to change it without
1794 * reconnecting.
1795 */
1796 if (modified == MODIFIED_TIMEOUT) {
1797 for (ii = 0; ii < ncomps; ii++) {
1798 if (!ISREMOTE(ii))
1799 continue;
1800 rw_rlock(&hio_remote_lock[ii]);
1801 if (!ISCONNECTED(gres, ii)) {
1802 rw_unlock(&hio_remote_lock[ii]);
1803 continue;
1804 }
1805 rw_unlock(&hio_remote_lock[ii]);
1806 if (proto_timeout(gres->hr_remotein,
1807 gres->hr_timeout) < 0) {
1808 pjdlog_errno(LOG_WARNING,
1809 "Unable to set connection timeout");
1810 }
1811 if (proto_timeout(gres->hr_remoteout,
1812 gres->hr_timeout) < 0) {
1813 pjdlog_errno(LOG_WARNING,
1814 "Unable to set connection timeout");
1815 }
1816 }
1817 } else {
1818 for (ii = 0; ii < ncomps; ii++) {
1819 if (!ISREMOTE(ii))
1820 continue;
1821 remote_close(gres, ii);
1822 }
1823 if (modified & MODIFIED_REMOTEADDR) {
1824 strlcpy(gres->hr_remoteaddr, res->hr_remoteaddr,
1825 sizeof(gres->hr_remoteaddr));
1826 }
1827 }
1828#undef MODIFIED_REMOTEADDR
1829#undef MODIFIED_REPLICATION
1830#undef MODIFIED_TIMEOUT
1831
1832 pjdlog_info("Configuration reloaded successfully.");
1833 return;
1834failed:
1835 if (newcfg != NULL) {
1836 if (newcfg->hc_controlconn != NULL)
1837 proto_close(newcfg->hc_controlconn);
1838 if (newcfg->hc_listenconn != NULL)
1839 proto_close(newcfg->hc_listenconn);
1840 yy_config_free(newcfg);
1841 }
1842 pjdlog_warning("Configuration not reloaded.");
1843}
1844
1729/*
1730 * Thread guards remote connections and reconnects when needed, handles
1731 * signals, etc.
1732 */
1733static void *
1734guard_thread(void *arg)
1735{
1736 struct hast_resource *res = arg;
1737 struct proto_conn *in, *out;
1738 unsigned int ii, ncomps;
1739 int timeout;
1740
1741 ncomps = HAST_NCOMPONENTS;
1845/*
1846 * Thread guards remote connections and reconnects when needed, handles
1847 * signals, etc.
1848 */
1849static void *
1850guard_thread(void *arg)
1851{
1852 struct hast_resource *res = arg;
1853 struct proto_conn *in, *out;
1854 unsigned int ii, ncomps;
1855 int timeout;
1856
1857 ncomps = HAST_NCOMPONENTS;
1742 /* The is only one remote component for now. */
1743#define ISREMOTE(no) ((no) == 1)
1744
1745 for (;;) {
1746 if (sigexit_received) {
1747 primary_exitx(EX_OK,
1748 "Termination signal received, exiting.");
1749 }
1858
1859 for (;;) {
1860 if (sigexit_received) {
1861 primary_exitx(EX_OK,
1862 "Termination signal received, exiting.");
1863 }
1864 if (sighup_received) {
1865 sighup_received = false;
1866 config_reload();
1867 }
1750 /*
1751 * If all the connection will be fine, we will sleep until
1752 * someone wakes us up.
1753 * If any of the connections will be broken and we won't be
1754 * able to connect, we will sleep only for RECONNECT_SLEEP
1755 * seconds so we can retry soon.
1756 */
1757 timeout = 0;

--- 47 unchanged lines hidden (view full) ---

1805 }
1806 } else {
1807 rw_unlock(&hio_remote_lock[ii]);
1808 }
1809 }
1810 (void)cv_timedwait(&hio_guard_cond, &hio_guard_lock, timeout);
1811 mtx_unlock(&hio_guard_lock);
1812 }
1868 /*
1869 * If all the connection will be fine, we will sleep until
1870 * someone wakes us up.
1871 * If any of the connections will be broken and we won't be
1872 * able to connect, we will sleep only for RECONNECT_SLEEP
1873 * seconds so we can retry soon.
1874 */
1875 timeout = 0;

--- 47 unchanged lines hidden (view full) ---

1923 }
1924 } else {
1925 rw_unlock(&hio_remote_lock[ii]);
1926 }
1927 }
1928 (void)cv_timedwait(&hio_guard_cond, &hio_guard_lock, timeout);
1929 mtx_unlock(&hio_guard_lock);
1930 }
1813#undef ISREMOTE
1814 /* NOTREACHED */
1815 return (NULL);
1816}
1931 /* NOTREACHED */
1932 return (NULL);
1933}