aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--initscripts.spec2
-rw-r--r--src/Makefile6
-rw-r--r--src/udev-kvm-check.c146
-rw-r--r--udev/rules.d/81-kvm-rhel.rules1
4 files changed, 154 insertions, 1 deletions
diff --git a/initscripts.spec b/initscripts.spec
index 9901fa94..de838dd4 100644
--- a/initscripts.spec
+++ b/initscripts.spec
@@ -187,6 +187,7 @@ rm -rf $RPM_BUILD_ROOT
%attr(2755,root,root) /usr/sbin/netreport
/usr/lib/udev/rules.d/*
/usr/lib/udev/rename_device
+/usr/lib/udev/udev-kvm-check
/usr/sbin/service
/usr/sbin/ppp-watch
%{_mandir}/man*/*
@@ -207,6 +208,7 @@ rm -rf $RPM_BUILD_ROOT
%ghost %attr(0600,root,utmp) /var/log/btmp
%ghost %attr(0664,root,utmp) /var/log/wtmp
%ghost %attr(0664,root,utmp) /var/run/utmp
+%ghost %attr(0644,root,root) /etc/sysconfig/kvm
%ghost %verify(not md5 size mtime) %config(noreplace,missingok) /etc/crypttab
%dir /usr/lib/tmpfiles.d
/usr/lib/tmpfiles.d/initscripts.conf
diff --git a/src/Makefile b/src/Makefile
index 07d1f1f9..f2842152 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@ CFLAGS+=$(RPM_OPT_FLAGS) -Wall -D_GNU_SOURCE
LDFLAGS+=$(RPM_LD_FLAGS)
PROGS=usernetctl netreport usleep ipcalc brandbot \
- ppp-watch consoletype genhostid rename_device
+ ppp-watch consoletype genhostid rename_device udev-kvm-check
PPPWATCH_OBJS=ppp-watch.o shvar.o
BRANDBOT_OBJS=brandbot.o shvar.o
CONSOLE_INIT_OBJS=console_init.o shvar.o
@@ -30,6 +30,7 @@ install:
install -m 755 sushell $(ROOT)/usr/sbin/sushell
install -m 755 brandbot $(ROOT)/usr/sbin/brandbot
install -m 755 rename_device $(ROOT)/usr/lib/udev/rename_device
+ install -m 755 udev-kvm-check $(ROOT)/usr/lib/udev/udev-kvm-check
install -m 644 genhostid.1 $(ROOT)$(mandir)/man1
install -m 644 netreport.1 $(ROOT)$(mandir)/man1
install -m 644 usleep.1 $(ROOT)$(mandir)/man1
@@ -77,3 +78,6 @@ ppp-watch.o: ppp-watch.c
rename_device: rename_device.c
$(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -o $@ $< `pkg-config glib-2.0 --libs`
+udev-kvm-check: udev-kvm-check.c
+ $(CC) $(CFLAGS) -o $@ $<
+
diff --git a/src/udev-kvm-check.c b/src/udev-kvm-check.c
new file mode 100644
index 00000000..43cb9d93
--- /dev/null
+++ b/src/udev-kvm-check.c
@@ -0,0 +1,146 @@
+#include <ctype.h>
+#include <syslog.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DEFAULT 0
+#define FACILITY "kvm"
+#define SYSCONFIG_KVM "/etc/sysconfig/kvm"
+
+#define COUNT_MSG \
+ "%d %s now active"
+
+#define SUBSCRIPTION_MSG \
+ "%d %s now active; your Red Hat Enterprise Linux subscription" \
+ " limit is %d guests. Please review your Red Hat Enterprise Linux" \
+ " subscription agreement or contact your Red Hat" \
+ " support representative for more information. You" \
+ " may review the Red Hat Enterprise subscription" \
+ " limits at http://www.redhat.com/rhel-virt-limits"
+
+int get_threshold_from_file(FILE *fp)
+{
+ static const char key[] = "THRESHOLD=";
+ int pos = 0;
+ int thres;
+ char ch;
+
+start:
+ /* State START - at beginning of line, search for beginning of "THRESHOLD="
+ * string.
+ */
+ ch = getc(fp);
+ if (ch == EOF) {
+ return DEFAULT;
+ }
+ if (isspace(ch)) {
+ goto start;
+ }
+ if (ch == 'T') {
+ pos = 1;
+ goto key;
+ }
+ goto eol;
+
+eol:
+ /* State EOL - loop until end of line */
+ ch = getc(fp);
+ if (ch == EOF) {
+ return DEFAULT;
+ }
+ if (ch == '\n') {
+ goto start;
+ }
+ goto eol;
+
+key:
+ /* State KEY - match "THRESHOLD=" string, go to THRESHOLD if found */
+ ch = getc(fp);
+ if (ch == EOF) {
+ return DEFAULT;
+ }
+ if (ch == key[pos]) {
+ pos++;
+ if (key[pos] == 0) {
+ goto threshold;
+ } else {
+ goto key;
+ }
+ }
+ goto eol;
+
+threshold:
+ /* State THRESHOLD - parse number using fscanf, expect comment or space
+ * or EOL.
+ */
+ ch = getc(fp);
+ if (ch == EOF) {
+ return DEFAULT;
+ }
+ if (!isdigit(ch)) {
+ goto eol;
+ }
+ ungetc(ch, fp);
+ if (fscanf(fp, "%d", &thres) != 1) {
+ return DEFAULT;
+ }
+ ch = getc(fp);
+ if (ch == '#' || ch == EOF || ch == '\n' || isspace(ch)) {
+ return thres;
+ }
+ goto eol;
+}
+
+int get_threshold()
+{
+ FILE *fp = fopen(SYSCONFIG_KVM, "r");
+ int val = get_threshold_from_file(fp);
+
+ fclose (fp);
+ return val;
+}
+
+const char *guest(int count)
+{
+ return (count == 1 ? "guest" : "guests");
+}
+
+void emit_count_message(int count)
+{
+ openlog(FACILITY, LOG_CONS, LOG_USER);
+ syslog(LOG_INFO, COUNT_MSG, count, guest(count));
+ closelog();
+}
+
+void emit_subscription_message(int count, int threshold)
+{
+ openlog(FACILITY, LOG_CONS, LOG_USER);
+ syslog(LOG_WARNING, SUBSCRIPTION_MSG, count, guest(count), threshold);
+ closelog();
+}
+
+int main(int argc, char **argv)
+{
+ int count, threshold;
+
+ if (argc < 3)
+ exit(1);
+
+ count = atoi(argv[1]);
+ threshold = get_threshold();
+
+ if (!strcmp(argv[2], "create")) {
+ if (threshold == 0) {
+ emit_count_message(count);
+ } else if (count > threshold) {
+ emit_subscription_message(count, threshold);
+ }
+ } else {
+ if (count >= threshold) {
+ emit_count_message(count);
+ }
+ }
+
+ return 0;
+}
diff --git a/udev/rules.d/81-kvm-rhel.rules b/udev/rules.d/81-kvm-rhel.rules
new file mode 100644
index 00000000..787cad62
--- /dev/null
+++ b/udev/rules.d/81-kvm-rhel.rules
@@ -0,0 +1 @@
+DEVPATH=="*/kvm", ACTION=="change", RUN+="/lib/udev/udev-kvm-check $env{COUNT} $env{EVENT}"