diff options
-rw-r--r-- | initscripts.spec | 2 | ||||
-rw-r--r-- | src/Makefile | 6 | ||||
-rw-r--r-- | src/udev-kvm-check.c | 146 | ||||
-rw-r--r-- | udev/rules.d/81-kvm-rhel.rules | 1 |
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}" |