Add plumbing for allowed partitions on reservations

Issue: 50466
Ticket: 23173
diff --git a/slurm/slurm.h b/slurm/slurm.h
index 88712c3..6eb360e 100644
--- a/slurm/slurm.h
+++ b/slurm/slurm.h
@@ -2728,6 +2728,7 @@
 
 typedef struct reserve_info {
 	char *accounts;		/* names of accounts permitted to use */
+	char *allowed_parts; /* names of partitions permitted to use */
 	char *burst_buffer;	/* burst buffer resources to be included */
 	char *comment;		/* arbitrary comment */
 	uint32_t core_cnt;	/* count of cores required */
@@ -2767,6 +2768,7 @@
 
 typedef struct resv_desc_msg {
 	char *accounts;		/* names of accounts permitted to use */
+	char *allowed_parts; /* names of partitions permitted to use */
 	char *burst_buffer;	/* burst buffer resources to be included */
 	char *comment;		/* arbitrary comment */
 	uint32_t core_cnt;	/* Count of cores required */
diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c
index 06d255e..818bba4 100644
--- a/src/common/slurm_protocol_defs.c
+++ b/src/common/slurm_protocol_defs.c
@@ -1988,6 +1988,8 @@
 		xfree(msg->burst_buffer);
 	if (res_free_flags & RESV_FREE_STR_COMMENT)
 		xfree(msg->comment);
+	if (res_free_flags & RESV_FREE_STR_ALLOWED_PARTS)
+		xfree(msg->allowed_parts);
 	if (res_free_flags & RESV_FREE_STR_QOS)
 		xfree(msg->qos);
 	if (res_free_flags & RESV_FREE_STR_TRES_LIC)
@@ -4399,6 +4401,7 @@
 	int i;
 	if (resv) {
 		xfree(resv->accounts);
+		xfree(resv->allowed_parts);
 		xfree(resv->burst_buffer);
 		xfree(resv->comment);
 		if (resv->core_spec) {
diff --git a/src/common/slurm_protocol_defs.h b/src/common/slurm_protocol_defs.h
index be92b99..fa2999e 100644
--- a/src/common/slurm_protocol_defs.h
+++ b/src/common/slurm_protocol_defs.h
@@ -220,7 +220,7 @@
 #define RESV_FREE_STR_TRES_BB   SLURM_BIT(2)
 #define RESV_FREE_STR_QOS SLURM_BIT(3)
 #define RESV_FREE_STR_TRES_LIC  SLURM_BIT(4)
-/* SLURM_BIT(5) unused */
+#define RESV_FREE_STR_ALLOWED_PARTS SLURM_BIT(5)
 #define RESV_FREE_STR_GROUP     SLURM_BIT(6)
 #define RESV_FREE_STR_COMMENT   SLURM_BIT(7)
 #define RESV_FREE_STR_NODES     SLURM_BIT(8)
diff --git a/src/common/slurm_protocol_pack.c b/src/common/slurm_protocol_pack.c
index abee87f..a4a47c9 100644
--- a/src/common/slurm_protocol_pack.c
+++ b/src/common/slurm_protocol_pack.c
@@ -2008,6 +2008,7 @@
 		pack32(msg->max_start_delay, buffer);
 		packstr(msg->partition,    buffer);
 		pack32(msg->purge_comp_time, buffer);
+		packstr(msg->allowed_parts, buffer);
 		packstr(msg->qos, buffer);
 		packstr(msg->users,        buffer);
 		packstr(msg->accounts,     buffer);
@@ -2069,6 +2070,7 @@
 		safe_unpackstr(&tmp_ptr->partition, buffer);
 		safe_unpack32(&tmp_ptr->purge_comp_time, buffer);
 
+		safe_unpackstr(&tmp_ptr->allowed_parts, buffer);
 		safe_unpackstr(&tmp_ptr->qos, buffer);
 		safe_unpackstr(&tmp_ptr->users, buffer);
 		safe_unpackstr(&tmp_ptr->accounts, buffer);
@@ -2996,6 +2998,7 @@
 		safe_unpackstr(&resv->users, buffer);
 		safe_unpackstr(&resv->groups, buffer);
 		safe_unpackstr(&resv->qos, buffer);
+		safe_unpackstr(&resv->allowed_parts, buffer);
 
 		unpack_bit_str_hex_as_inx(&resv->node_inx, buffer);
 
diff --git a/src/slurmctld/reservation.c b/src/slurmctld/reservation.c
index a91a937..ec9a783 100644
--- a/src/slurmctld/reservation.c
+++ b/src/slurmctld/reservation.c
@@ -567,6 +567,10 @@
 	resv_copy_ptr->node_list = xstrdup(resv_orig_ptr->node_list);
 	resv_copy_ptr->partition = xstrdup(resv_orig_ptr->partition);
 	resv_copy_ptr->part_ptr = resv_orig_ptr->part_ptr;
+	resv_copy_ptr->allowed_parts = xstrdup(resv_orig_ptr->allowed_parts);
+	if (resv_orig_ptr->allowed_parts_list)
+		resv_copy_ptr->allowed_parts_list =
+			list_shallow_copy(resv_orig_ptr->allowed_parts_list);
 	resv_copy_ptr->qos = xstrdup(resv_orig_ptr->qos);
 	if (resv_orig_ptr->qos_list)
 		resv_copy_ptr->qos_list =
@@ -675,6 +679,10 @@
 
 	dest_resv->part_ptr = src_resv->part_ptr;
 
+	FREE_NULL_LIST(dest_resv->allowed_parts_list);
+	dest_resv->allowed_parts_list = src_resv->allowed_parts_list;
+	src_resv->allowed_parts_list = NULL;
+
 	xfree(dest_resv->qos);
 	dest_resv->qos = src_resv->qos;
 	src_resv->qos = NULL;
@@ -747,6 +755,8 @@
 		FREE_NULL_BITMAP(resv_ptr->node_bitmap);
 		xfree(resv_ptr->node_list);
 		xfree(resv_ptr->partition);
+		xfree(resv_ptr->allowed_parts);
+		FREE_NULL_LIST(resv_ptr->allowed_parts_list);
 		xfree(resv_ptr->qos);
 		FREE_NULL_LIST(resv_ptr->qos_list);
 		xfree(resv_ptr->tres_str);
@@ -2409,6 +2419,7 @@
 		packstr(resv_ptr->users,	buffer);
 		packstr(resv_ptr->groups, buffer);
 		packstr(resv_ptr->qos, buffer);
+		packstr(resv_ptr->allowed_parts, buffer);
 
 		if (internal) {
 			packstr(resv_ptr->assoc_list,	buffer);
@@ -2564,6 +2575,7 @@
 		safe_unpackstr(&resv_ptr->users, buffer);
 		safe_unpackstr(&resv_ptr->groups, buffer);
 		safe_unpackstr(&resv_ptr->qos, buffer);
+		safe_unpackstr(&resv_ptr->allowed_parts, buffer);
 
 		/* Fields saved for internal use only (save state) */
 		safe_unpackstr(&resv_ptr->assoc_list, buffer);
diff --git a/src/slurmctld/slurmctld.h b/src/slurmctld/slurmctld.h
index 18aaa53..429591a 100644
--- a/src/slurmctld/slurmctld.h
+++ b/src/slurmctld/slurmctld.h
@@ -342,6 +342,7 @@
 #define RESV_CTLD_EPILOG SLURM_BIT(4)
 #define RESV_CTLD_PROLOG SLURM_BIT(5)
 #define RESV_CTLD_QOS_NOT SLURM_BIT(6)
+#define RESV_CTLD_ALLOWED_PARTS_NOT SLURM_BIT(7)
 
 typedef struct slurmctld_resv {
 	uint16_t magic;		/* magic cookie, RESV_MAGIC		*/
@@ -349,6 +350,9 @@
 	char *accounts;		/* names of accounts permitted to use	*/
 	int account_cnt;	/* count of accounts permitted to use	*/
 	char **account_list;	/* list of accounts permitted to use	*/
+	char *allowed_parts; /* names of partitions permitted to use */
+	list_t *allowed_parts_list; /* pointers to partitions permitted or not
+				     * to use */
 	char *assoc_list;	/* list of associations			*/
 	uint32_t boot_time;	/* time it would take to reboot a node	*/
 	char *burst_buffer;	/* burst buffer resources		*/