aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2013-11-13 19:31:40 +0100
committerVáclav Pavlín <vpavlin@redhat.com>2013-11-14 15:03:17 +0100
commit286aaf42aa5afef6734086f64285f8c4cced359d (patch)
treebcc18b8e50dcd9e554002332f9078b4abadc3d0b /src
parentf9a6c0385f49bdcd8db02ce3d5128a856077e889 (diff)
downloadinitscripts-286aaf42aa5afef6734086f64285f8c4cced359d.tar
initscripts-286aaf42aa5afef6734086f64285f8c4cced359d.tar.gz
initscripts-286aaf42aa5afef6734086f64285f8c4cced359d.tar.bz2
initscripts-286aaf42aa5afef6734086f64285f8c4cced359d.tar.xz
initscripts-286aaf42aa5afef6734086f64285f8c4cced359d.zip
provide KVM guest count and limit info message (C implementation) (#1014731)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile6
-rw-r--r--src/udev-kvm-check.c146
2 files changed, 151 insertions, 1 deletions
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;
+}