From 286aaf42aa5afef6734086f64285f8c4cced359d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 13 Nov 2013 19:31:40 +0100 Subject: provide KVM guest count and limit info message (C implementation) (#1014731) --- src/Makefile | 6 ++- src/udev-kvm-check.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 src/udev-kvm-check.c (limited to 'src') 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 +#include +#include +#include +#include + +#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; +} -- cgit v1.2.1