RE: [PATCH] Protect RFKILL under CONFIG_RFKILL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi list,

Is this a patch that's likely to be picked-up?

We have a platform that doesn't support RFKILL, and need to suppress the error
messages that occur when wpa_supplicant is started on that platform. Also removing
RFKILL support makes the binary marginally smaller, which benefits our low-end
resource-constrained platform.

Disclosure: We are the ones that asked GES to develop this patch.

MV

> -----Original Message-----
> From: Hostap [mailto:hostap-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of
> ps.harsha@xxxxxxxxxxxxxxxxxx
> Sent: April 06, 2017 05:10
> To: hostap@xxxxxxxxxxxxxxxxxxx
> Cc: Eranna, Vinay (Vinay) **CTR**; Sakre, Harsha (Harsha) **CTR**
> Subject: [PATCH] Protect RFKILL under CONFIG_RFKILL
> 
> From: Harsha <ps.harsha@xxxxxxxxxxxxxxxxxx>
> 
> Hi,
> 
> We are working on a platform which will not support RFKILL functionality.
> So we tried to disable RFKILL in wpa_supplicant. Disabling NEED_RFKILL config
> option in drivers.mak and drivers.mk was not disabling the complete RFKILL
> functionality in wpa_supplicant. So provided an option
> (CONFIG_RFKILL) in defconfig to enable and disable rfkill functionality in
> wpa_supplicant. CONFIG_RFKILL macro is used to protect RFKILL part of code
> in wpa_supplicant.
> 
> RFKILL functionality disable option is required in the case where execution
> platform doesnot support RFKILL functionality.
> 
> Signed-off-by: Harsha Sakre P <ps.harsha@xxxxxxxxxxxxxxxxxx>
> ---
>  src/drivers/driver.h              |  2 ++
>  src/drivers/driver_common.c       |  7 +++++--
>  src/drivers/driver_nl80211.c      | 33 ++++++++++++++++++++++++++++-----
>  src/drivers/driver_nl80211.h      |  2 ++
>  src/drivers/driver_nl80211_capa.c |  2 ++
>  src/drivers/driver_wext.c         | 28 +++++++++++++++++++++++++++-
>  src/drivers/driver_wext.h         |  2 ++
>  src/drivers/drivers.mak           | 12 +++++-------
>  src/drivers/drivers.mk            | 12 +++++-------
>  wpa_supplicant/defconfig          |  5 +++++
>  10 files changed, 83 insertions(+), 22 deletions(-)
> 
> diff --git a/src/drivers/driver.h b/src/drivers/driver.h index fc2593e..5d9ac7e
> 100644
> --- a/src/drivers/driver.h
> +++ b/src/drivers/driver.h
> @@ -1026,7 +1026,9 @@ struct wowlan_triggers {
>  	u8 gtk_rekey_failure;
>  	u8 eap_identity_req;
>  	u8 four_way_handshake;
> +#ifdef CONFIG_RFKILL
>  	u8 rfkill_release;
> +#endif
>  };
> 
>  struct wpa_driver_ap_params {
> diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
> index 220b7d4..475a920 100644
> --- a/src/drivers/driver_common.c
> +++ b/src/drivers/driver_common.c
> @@ -201,8 +201,11 @@ wpa_get_wowlan_triggers(const char
> *wowlan_triggers,
>  		    !CHECK_TRIGGER(magic_pkt) &&
>  		    !CHECK_TRIGGER(gtk_rekey_failure) &&
>  		    !CHECK_TRIGGER(eap_identity_req) &&
> -		    !CHECK_TRIGGER(four_way_handshake) &&
> -		    !CHECK_TRIGGER(rfkill_release)) {
> +		    !CHECK_TRIGGER(four_way_handshake)
> +#ifdef CONFIG_RFKILL
> +		    && !CHECK_TRIGGER(rfkill_release) #endif
> +		) {
>  			wpa_printf(MSG_DEBUG,
>  				   "Unknown/unsupported wowlan trigger
> '%s'",
>  				   start);
> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index
> bceeba2..c6d07d7 100644
> --- a/src/drivers/driver_nl80211.c
> +++ b/src/drivers/driver_nl80211.c
> @@ -36,7 +36,9 @@
>  #include "linux_ioctl.h"
>  #include "radiotap.h"
>  #include "radiotap_iter.h"
> +#ifdef CONFIG_RFKILL
>  #include "rfkill.h"
> +#endif
>  #include "driver_nl80211.h"
> 
> 
> @@ -1648,6 +1650,7 @@ static void nl80211_check_global(struct
> nl80211_global *global)  }
> 
> 
> +#ifdef CONFIG_RFKILL
>  static void wpa_driver_nl80211_rfkill_blocked(void *ctx)  {
>  	struct wpa_driver_nl80211_data *drv = ctx; @@ -1683,6 +1686,7 @@
> static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
>  	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
>  		wpa_supplicant_event(drv->ctx,
> EVENT_INTERFACE_ENABLED, NULL);  }
> +#endif
> 
> 
>  static void wpa_driver_nl80211_handle_eapol_tx_status(int sock, @@ -
> 1766,6 +1770,7 @@ static void nl80211_destroy_bss(struct i802_bss *bss)  }
> 
> 
> +#ifdef CONFIG_RFKILL
>  static void
>  wpa_driver_nl80211_drv_init_rfkill(struct wpa_driver_nl80211_data *drv)  {
> @@ -1817,6 +1822,7 @@ wpa_driver_nl80211_drv_init_rfkill(struct
> wpa_driver_nl80211_data *drv)
>  		os_free(rcfg);
>  	}
>  }
> +#endif
> 
> 
>  static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
> @@ -2287,10 +2293,12 @@ static void nl80211_mgmt_unsubscribe(struct
> i802_bss *bss, const char *reason)  }
> 
> 
> +#ifdef CONFIG_RFKILL
>  static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void
> *timeout_ctx)  {
>  	wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED,
> NULL);  }
> +#endif
> 
> 
>  static void nl80211_del_p2pdev(struct i802_bss *bss) @@ -2399,7 +2407,9
> @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data
> *drv,
>  				   const char *driver_params)
>  {
>  	struct i802_bss *bss = drv->first_bss;
> +#ifdef CONFIG_RFKILL
>  	int send_rfkill_event = 0;
> +#endif
>  	enum nl80211_iftype nlmode;
> 
>  	drv->ifindex = if_nametoindex(bss->ifname); @@ -2453,9 +2463,12
> @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data
> *drv,
>  	if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
>  		nl80211_get_macaddr(bss);
> 
> +#ifdef CONFIG_RFKILL
>  	wpa_driver_nl80211_drv_init_rfkill(drv);
> 
> -	if (!rfkill_is_blocked(drv->rfkill)) {
> +	if (!rfkill_is_blocked(drv->rfkill))
> +#endif
> +	{
>  		int ret = i802_set_iface_flags(bss, 1);
>  		if (ret) {
>  			wpa_printf(MSG_ERROR, "nl80211: Could not set "
> @@ -2469,7 +2482,9 @@ wpa_driver_nl80211_finish_drv_init(struct
> wpa_driver_nl80211_data *drv,
> 
>  		if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
>  			return ret;
> -	} else {
> +	}
> +#ifdef CONFIG_RFKILL
> +	else {
>  		wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
>  			   "interface '%s' due to rfkill", bss->ifname);
>  		if (nlmode != NL80211_IFTYPE_P2P_DEVICE) @@ -2477,6
> +2492,7 @@ wpa_driver_nl80211_finish_drv_init(struct
> wpa_driver_nl80211_data *drv,
> 
>  		send_rfkill_event = 1;
>  	}
> +#endif
> 
>  	if (!drv->hostapd && nlmode != NL80211_IFTYPE_P2P_DEVICE)
>  		netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
> @@ -2489,10 +2505,12 @@ wpa_driver_nl80211_finish_drv_init(struct
> wpa_driver_nl80211_data *drv,
>  		os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
>  	}
> 
> +#ifdef CONFIG_RFKILL
>  	if (send_rfkill_event) {
>  		eloop_register_timeout(0, 0,
> wpa_driver_nl80211_send_rfkill,
>  				       drv, drv->ctx);
>  	}
> +#endif
> 
>  	if (drv->vendor_cmd_test_avail)
>  		qca_vendor_test(drv);
> @@ -2579,8 +2597,10 @@ static void wpa_driver_nl80211_deinit(struct
> i802_bss *bss)
> 
>  	netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
>  			       IF_OPER_UP);
> +#ifdef CONFIG_RFKILL
>  	eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv-
> >ctx);
>  	rfkill_deinit(drv->rfkill);
> +#endif
> 
>  	eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv-
> >ctx);
> 
> @@ -8638,9 +8658,12 @@ static int nl80211_set_wowlan(void *priv,
>  	    (triggers->eap_identity_req &&
>  	     nla_put_flag(msg,
> NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
>  	    (triggers->four_way_handshake &&
> -	     nla_put_flag(msg,
> NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
> -	    (triggers->rfkill_release &&
> -	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) {
> +	     nla_put_flag(msg,
> NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
> +#ifdef CONFIG_RFKILL
> +	    || (triggers->rfkill_release &&
> +	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
> +#endif
> +	) {
>  		nlmsg_free(msg);
>  		return -ENOBUFS;
>  	}
> diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index
> 7e1f52c..1682f25 100644
> --- a/src/drivers/driver_nl80211.h
> +++ b/src/drivers/driver_nl80211.h
> @@ -93,7 +93,9 @@ struct wpa_driver_nl80211_data {
>  	int if_removed;
>  	int if_disabled;
>  	int ignore_if_down_event;
> +#ifdef CONFIG_RFKILL
>  	struct rfkill_data *rfkill;
> +#endif
>  	struct wpa_driver_capa capa;
>  	u8 *extended_capa, *extended_capa_mask;
>  	unsigned int extended_capa_len;
> diff --git a/src/drivers/driver_nl80211_capa.c
> b/src/drivers/driver_nl80211_capa.c
> index f67ad21..ddbfa60 100644
> --- a/src/drivers/driver_nl80211_capa.c
> +++ b/src/drivers/driver_nl80211_capa.c
> @@ -513,8 +513,10 @@ static void wiphy_info_wowlan_triggers(struct
> wpa_driver_capa *capa,
>  		capa->wowlan_triggers.eap_identity_req = 1;
>  	if (triggers[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
>  		capa->wowlan_triggers.four_way_handshake = 1;
> +#ifdef CONFIG_RFKILL
>  	if (triggers[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
>  		capa->wowlan_triggers.rfkill_release = 1;
> +#endif
>  }
> 
> 
> diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index
> 47b90eb..f36e472 100644
> --- a/src/drivers/driver_wext.c
> +++ b/src/drivers/driver_wext.c
> @@ -28,7 +28,9 @@
>  #include "priv_netlink.h"
>  #include "netlink.h"
>  #include "linux_ioctl.h"
> +#ifdef CONFIG_RFKILL
>  #include "rfkill.h"
> +#endif
>  #include "driver.h"
>  #include "driver_wext.h"
> 
> @@ -731,6 +733,7 @@ static void wpa_driver_wext_event_rtm_dellink(void
> *ctx, struct ifinfomsg *ifi,  }
> 
> 
> +#ifdef CONFIG_RFKILL
>  static void wpa_driver_wext_rfkill_blocked(void *ctx)  {
>  	wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked"); @@ -752,6
> +755,7 @@ static void wpa_driver_wext_rfkill_unblocked(void *ctx)
>  	}
>  	/* rtnetlink ifup handler will report interface as enabled */  }
> +#endif
> 
> 
>  static void wext_get_phy_name(struct wpa_driver_wext_data *drv) @@ -
> 798,7 +802,11 @@ void * wpa_driver_wext_init(void *ctx, const char
> *ifname)  {
>  	struct wpa_driver_wext_data *drv;
>  	struct netlink_config *cfg;
> +
> +#ifdef CONFIG_RFKILL
>  	struct rfkill_config *rcfg;
> +#endif
> +
>  	char path[128];
>  	struct stat buf;
> 
> @@ -834,6 +842,7 @@ void * wpa_driver_wext_init(void *ctx, const char
> *ifname)
>  		goto err2;
>  	}
> 
> +#ifdef CONFIG_RFKILL
>  	rcfg = os_zalloc(sizeof(*rcfg));
>  	if (rcfg == NULL)
>  		goto err3;
> @@ -846,6 +855,7 @@ void * wpa_driver_wext_init(void *ctx, const char
> *ifname)
>  		wpa_printf(MSG_DEBUG, "WEXT: RFKILL status not
> available");
>  		os_free(rcfg);
>  	}
> +#endif
> 
>  	drv->mlme_sock = -1;
> 
> @@ -857,7 +867,9 @@ void * wpa_driver_wext_init(void *ctx, const char
> *ifname)
>  	return drv;
> 
>  err3:
> +#ifdef CONFIG_RFKILL
>  	rfkill_deinit(drv->rfkill);
> +#endif
>  	netlink_deinit(drv->netlink);
>  err2:
>  	close(drv->ioctl_sock);
> @@ -867,10 +879,12 @@ err1:
>  }
> 
> 
> +#ifdef CONFIG_RFKILL
>  static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void
> *timeout_ctx)  {
>  	wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED,
> NULL);  }
> +#endif
> 
> 
>  static int wext_hostap_ifname(struct wpa_driver_wext_data *drv, @@ -
> 974,16 +988,22 @@ static void wext_check_hostap(struct
> wpa_driver_wext_data *drv)
> 
>  static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data
> *drv)  {
> +#ifdef CONFIG_RFKILL
>  	int send_rfkill_event = 0;
> +#endif
> 
>  	if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) {
> +#ifdef CONFIG_RFKILL
>  		if (rfkill_is_blocked(drv->rfkill)) {
>  			wpa_printf(MSG_DEBUG, "WEXT: Could not yet
> enable "
>  				   "interface '%s' due to rfkill",
>  				   drv->ifname);
>  			drv->if_disabled = 1;
>  			send_rfkill_event = 1;
> -		} else {
> +		} else
> +#endif
> +
> +		{
>  			wpa_printf(MSG_ERROR, "WEXT: Could not set "
>  				   "interface '%s' UP", drv->ifname);
>  			return -1;
> @@ -1017,10 +1037,12 @@ static int wpa_driver_wext_finish_drv_init(struct
> wpa_driver_wext_data *drv)
>  	netlink_send_oper_ifla(drv->netlink, drv->ifindex,
>  			       1, IF_OPER_DORMANT);
> 
> +#ifdef CONFIG_RFKILL
>  	if (send_rfkill_event) {
>  		eloop_register_timeout(0, 0, wpa_driver_wext_send_rfkill,
>  				       drv, drv->ctx);
>  	}
> +#endif
> 
>  	return 0;
>  }
> @@ -1040,7 +1062,9 @@ void wpa_driver_wext_deinit(void *priv)
>  	wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED,
> 0);
> 
>  	eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv-
> >ctx);
> +#ifdef CONFIG_RFKILL
>  	eloop_cancel_timeout(wpa_driver_wext_send_rfkill, drv, drv->ctx);
> +#endif
> 
>  	/*
>  	 * Clear possibly configured driver parameters in order to make it
> @@ -1050,7 +1074,9 @@ void wpa_driver_wext_deinit(void *priv)
> 
>  	netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP);
>  	netlink_deinit(drv->netlink);
> +#ifdef CONFIG_RFKILL
>  	rfkill_deinit(drv->rfkill);
> +#endif
> 
>  	if (drv->mlme_sock >= 0)
>  		eloop_unregister_read_sock(drv->mlme_sock);
> diff --git a/src/drivers/driver_wext.h b/src/drivers/driver_wext.h index
> b4b5960..4e1608d 100644
> --- a/src/drivers/driver_wext.h
> +++ b/src/drivers/driver_wext.h
> @@ -22,7 +22,9 @@ struct wpa_driver_wext_data {
>  	int ifindex2;
>  	int if_removed;
>  	int if_disabled;
> +#ifdef CONFIG_RFKILL
>  	struct rfkill_data *rfkill;
> +#endif
>  	u8 *assoc_req_ies;
>  	size_t assoc_req_ies_len;
>  	u8 *assoc_resp_ies;
> diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak index
> 1496b47..4891638 100644
> --- a/src/drivers/drivers.mak
> +++ b/src/drivers/drivers.mak
> @@ -49,7 +49,6 @@ NEED_SME=y
>  NEED_AP_MLME=y
>  NEED_NETLINK=y
>  NEED_LINUX_IOCTL=y
> -NEED_RFKILL=y
>  NEED_RADIOTAP=y
> 
>  ifdef CONFIG_LIBNL32
> @@ -136,7 +135,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
> CONFIG_WIRELESS_EXTENSION=y  NEED_NETLINK=y  NEED_LINUX_IOCTL=y
> -NEED_RFKILL=y  endif
> 
>  ifdef CONFIG_DRIVER_NDIS
> @@ -162,7 +160,6 @@ endif
>  ifdef CONFIG_WIRELESS_EXTENSION
>  DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION  DRV_WPA_OBJS
> += ../src/drivers/driver_wext.o -NEED_RFKILL=y  endif
> 
>  ifdef NEED_NETLINK
> @@ -173,14 +170,15 @@ ifdef NEED_LINUX_IOCTL  DRV_OBJS +=
> ../src/drivers/linux_ioctl.o  endif
> 
> -ifdef NEED_RFKILL
> -DRV_OBJS += ../src/drivers/rfkill.o
> -endif
> -
>  ifdef NEED_RADIOTAP
>  DRV_OBJS += ../src/utils/radiotap.o
>  endif
> 
> +ifdef CONFIG_RFKILL
> +DRV_CFLAGS += -DCONFIG_RFKILL
> +DRV_OBJS += ../src/drivers/rfkill.o
> +endif
> +
>  ifdef CONFIG_VLAN_NETLINK
>  ifdef CONFIG_FULL_DYNAMIC_VLAN
>  ifdef CONFIG_LIBNL32
> diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk index
> cd25133..cd2b6f5 100644
> --- a/src/drivers/drivers.mk
> +++ b/src/drivers/drivers.mk
> @@ -44,7 +44,6 @@ NEED_SME=y
>  NEED_AP_MLME=y
>  NEED_NETLINK=y
>  NEED_LINUX_IOCTL=y
> -NEED_RFKILL=y
>  NEED_RADIOTAP=y
> 
>  ifdef CONFIG_LIBNL32
> @@ -120,7 +119,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
> CONFIG_WIRELESS_EXTENSION=y  NEED_NETLINK=y  NEED_LINUX_IOCTL=y
> -NEED_RFKILL=y  endif
> 
>  ifdef CONFIG_DRIVER_NDIS
> @@ -146,7 +144,6 @@ endif
>  ifdef CONFIG_WIRELESS_EXTENSION
>  DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION  DRV_WPA_OBJS
> += src/drivers/driver_wext.c -NEED_RFKILL=y  endif
> 
>  ifdef NEED_NETLINK
> @@ -157,14 +154,15 @@ ifdef NEED_LINUX_IOCTL  DRV_OBJS +=
> src/drivers/linux_ioctl.c  endif
> 
> -ifdef NEED_RFKILL
> -DRV_OBJS += src/drivers/rfkill.c
> -endif
> -
>  ifdef NEED_RADIOTAP
>  DRV_OBJS += src/utils/radiotap.c
>  endif
> 
> +ifdef CONFIG_RFKILL
> +DRV_CFLAGS += -DCONFIG_RFKILL
> +DRV_OBJS += src/drivers/rfkill.c
> +endif
> +
>  ifdef CONFIG_DRIVER_CUSTOM
>  DRV_CFLAGS += -DCONFIG_DRIVER_CUSTOM
>  endif
> diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig index
> 307f82d..7f0ea38 100644
> --- a/wpa_supplicant/defconfig
> +++ b/wpa_supplicant/defconfig
> @@ -587,3 +587,8 @@ CONFIG_PEERKEY=y
>  # Opportunistic Wireless Encryption (OWE)  # Experimental implementation
> of draft-harkins-owe-07.txt  #CONFIG_OWE=y
> +
> +# Enable/Disable RFKILL in wpa_supplicant.
> +# This option can be used to Enable/Disable RFKILL functionality in #
> +wpa_supplicant based on rfkill support in execution platform (default is y).
> +CONFIG_RFKILL=y
> --
> 1.9.1
> 
> Disclaimer:- The information contained in this electronic message and any
> attachments to this message are intended for the exclusive use of the
> addressee(s) and may contain proprietary, confidential or privileged
> information. If you are not the intended recipient, you should not
> disseminate, distribute or copy this e-mail. Please notify the sender
> immediately and destroy all copies of this message and any attachments. The
> views expressed in this E-mail message (including the enclosure/(s) or
> attachment/(s) if any) are those of the individual sender, except where the
> sender expressly, and with authority, states them to be the views of
> GlobalEdge. Before opening any mail and attachments please check them for
> viruses .GlobalEdge does not accept any liability for virus infected mails.
> 
> 
> _______________________________________________
> Hostap mailing list
> Hostap@xxxxxxxxxxxxxxxxxxx
> http://lists.infradead.org/mailman/listinfo/hostap

_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux